1.14.4 Keeping Color Names when renaming

Discussion in 'Spigot Plugin Development' started by AVCK, Jan 17, 2020.

  1. I want to make a plugin that will keep the color when renaming. this is the code.
    Code (Java):
    public class Anvil implements Listener {

        @EventHandler
        public void onPrepareAnvil(PrepareAnvilEvent event) {
            //Get item in first slot
            ItemStack firstSlot = event.getInventory().getItem(0);
            //Get resulting item of inventory
            ItemStack resultItem = event.getResult();

            //Check if resulting item is valid (you should probably also do this for firstSlot)
            if(resultItem.getType() != Material.AIR && resultItem.hasItemMeta()) {
                ItemMeta meta = resultItem.getItemMeta();
                if(resultItem.getItemMeta().hasDisplayName()) {

                    //Set the display name
                    meta.setDisplayName(firstSlot.getItemMeta().getDisplayName());
                    resultItem.setItemMeta(meta);
                    //Set the resulting item
                    event.setResult(resultItem);
                }
            }
        }

        @EventHandler
        public void onInventoryClick(InventoryClickEvent e) {
            if (e.getInventory().getType() == InventoryType.ANVIL ) {
                if (e.getInventory().getItem(0) != null) {

                    if (e.getRawSlot() == 2) {
                        String n = String.valueOf(e.getRawSlot());
                        Bukkit.broadcastMessage(n);
                        if ((e.getInventory().getItem(2).getEnchantmentLevel(Enchantment.DAMAGE_ALL) > 5
                                || e.getInventory().getItem(2).getEnchantmentLevel(Enchantment.ARROW_DAMAGE) > 5
                                || e.getInventory().getItem(2).getEnchantmentLevel(Enchantment.DIG_SPEED) > 5
                                || e.getInventory().getItem(2).getEnchantmentLevel(Enchantment.PROTECTION_ENVIRONMENTAL) > 4)) {


                            Player p = (Player) e.getWhoClicked();

                            Bukkit.broadcastMessage("1");

                            if (Bindenchant.globalMap.get(p) == 0) {
                                p.sendMessage(ChatColor.DARK_RED + "You don't have repair credits!");
                                e.setCancelled(true);
                                Bukkit.broadcastMessage("2");
                            } else if (Bindenchant.globalMap.get(p) > 0) {
                                int a = Bindenchant.globalMap.get(p) - 1;
                                Bindenchant.globalMap.put(p, a);
                                ItemStack finalitem = e.getInventory().getItem(2);
                                p.setItemOnCursor(finalitem);

                                ItemStack air = new ItemStack(Material.AIR);
                                e.getInventory().setItem(0,air);
                                e.getInventory().setItem(1,air);
                                e.getInventory().setItem(2,air);
                                Bukkit.broadcastMessage("3");
                                p.sendMessage(ChatColor.GREEN + "Your item has been successfully repaired. Your remaining credit is " + a + ".");
                            } else if (Bindenchant.globalMap.get(p) == null) {
                                p.sendMessage(ChatColor.DARK_RED + "You don't have repair credits!");
                                e.setCancelled(true);
                                Bukkit.broadcastMessage("4");
                                Bindenchant.globalMap.put(p, 0);
                            }

                        }
                    }
                }
            }

        }
    }

     


    When I click the result item, the repair is finished but then the item on my cursor is just the name before the rename. Lets say I had a weapon with a name of [Name], and i want to rename it to [Rename]. The final slot of the anvil is visually showing [Rename] but when I click it and drag it to my inventory, it is set back to [Name]. I tried setting the item on the mouse cursor, but this also doesn't work. Help!
     
  2. How about using inventoryclickevent instead and checking if the clicked item is in the third slot then you can rename it to whatever you put, while taking out color codes from the first name

    PrepareAnvilEvent works each time you put an item not when they are clicked or taken out
     
  3. How can I get the name of whatever I put in an InventoryClickEvent?
     
  4. What do you mean by name?
    The name of the inventory? item?
    Either way, you need to look at other threads(Any thread that uses the InventoryClickEvent would work, really) or the javadocs before asking a question
     
  5. I need to know how to pass the string that the player is wishing to rename an item to to an InventoryClickEvent.
     
  6. So right now, all I need to do is pass the User-inputted string in the Anvil GUI. This would solve my problem pretty easy. Can anyone help me find how to do this?
     
  7. An alternative way to solve your problem is to get the output item name and translate the real color codes so that it shows as it should
     
  8. But is there a way to get the User-inputted string in the Anvil GUI?
     
  9. You’re getting the result item meta, but then turning its name to the first one. It’s just going to give the result item the same name as the first item.
    Edit: If you want to re name it this way and have it retain the color code, check what color code it has with the initial name and rename the result name to that initial result name, but with color, then set the result to that meta and it should work like a charm.
     
    #11 LukeEff, Jan 19, 2020
    Last edited: Jan 19, 2020
  10. How do I check the color code?
     
  11. It’s ~1:00 AM, so if there’s a better way, anybody can step in and correct me:

    Get the String of the name of the original item; ill say it’s originalFoo
    Get the String of the name of the result item; ill say it’s resultFoo

    Build a loop that contains a single if statement that looks for the matching names, like:

    if (originalFoo.equals(ChatColor.AQUA + resultFoo) {
    newName = ChatColor.AQUA + resultFoo;
    meta.setDisplayName(newName);
    resultItem.setItemMeta(meta);
    event.setResult(resultItem);
    }

    And don’t forget to do this efficiently. By that I mean create a variable that holds each ChatColor and then throw that all in a loop or something.
     
  12. Code (Java):


    public class Anvil implements Listener {

        @EventHandler
        public void onPrepareAnvil(PrepareAnvilEvent e) {

            ItemStack firstSlot = e.getInventory().getItem(0);

            ItemStack resultItem = e.getResult();
            if (!resultItem.getType().equals(Material.AIR) && resultItem.hasItemMeta()) {
                ItemMeta meta = resultItem.getItemMeta();
                if (resultItem.getItemMeta().hasDisplayName()) {

                    //Set the display name
                    meta.setDisplayName( firstSlot.getItemMeta().getDisplayName());

                    //Set the resulting item
                    e.setResult(resultItem);

                }
            }

        }
        @EventHandler
        public void OnPlayerClick(InventoryClickEvent event) {
            Player p = (Player) event.getWhoClicked();

            if (event.getInventory().getType() == InventoryType.ANVIL) {
                if (event.getRawSlot() == 2) {
                    ItemStack firstSlot = event.getInventory().getItem(0);
                    ItemStack secondSlot = event.getInventory().getItem(1);
                    ItemStack result = event.getInventory().getItem(2);
                    if (firstSlot.getEnchantmentLevel(Enchantment.DAMAGE_ALL) > 5
                            || firstSlot.getEnchantmentLevel(Enchantment.PROTECTION_ENVIRONMENTAL) > 4
                            || firstSlot.getEnchantmentLevel(Enchantment.DIG_SPEED) > 5
                            || firstSlot.getEnchantmentLevel(Enchantment.ARROW_DAMAGE) > 5
                    ) {
                        if (Bindenchant.globalMap.get(p) == null) {
                            event.setCancelled(true);
                            p.sendMessage(ChatColor.DARK_RED + "You didn't even buy repair credit? Cringe.");
                            Bindenchant.globalMap.put(p, 0);


                        } else if (Bindenchant.globalMap.get(p) > 0) {

                            AnvilInventory anvil = (AnvilInventory) event.getInventory();
                            String renameString = anvil.getRenameText();
                            ItemMeta itemMeta = result.getItemMeta();
                            if (firstSlot.getItemMeta().getDisplayName().equals(ChatColor.RED + firstSlot.getItemMeta().getDisplayName())){
                                itemMeta.setDisplayName(ChatColor.RED+ renameString);
                                result.setItemMeta(itemMeta);
                                int a = Bindenchant.globalMap.get(p) - 1;
                                Bindenchant.globalMap.put(p, a);
                                p.sendMessage(ChatColor.GREEN + "Your item has been successfully repaired! Your remaining credit is " + a + ".");
                            }else if (firstSlot.getItemMeta().getDisplayName().equals(ChatColor.GREEN + firstSlot.getItemMeta().getDisplayName())){
                                itemMeta.setDisplayName(ChatColor.GREEN+ renameString);
                                result.setItemMeta(itemMeta);
                                int a = Bindenchant.globalMap.get(p) - 1;
                                Bindenchant.globalMap.put(p, a);
                                p.sendMessage(ChatColor.GREEN + "Your item has been successfully repaired! Your remaining credit is " + a + ".");
                            }else if (firstSlot.getItemMeta().getDisplayName().equals(  ChatColor.RED + "" + ChatColor.BOLD + firstSlot.getItemMeta().getDisplayName())){
                                itemMeta.setDisplayName(  ChatColor.RED + "" + ChatColor.BOLD + renameString);
                                result.setItemMeta(itemMeta);
                                int a = Bindenchant.globalMap.get(p) - 1;
                                Bindenchant.globalMap.put(p, a);
                                p.sendMessage(ChatColor.GREEN + "Your item has been successfully repaired! Your remaining credit is " + a + ".");
                            }else if (firstSlot.getItemMeta().getDisplayName().equals(  ChatColor.GOLD + "" + ChatColor.BOLD + firstSlot.getItemMeta().getDisplayName())){
                                itemMeta.setDisplayName(  ChatColor.GOLD + "" + ChatColor.BOLD + renameString);
                                result.setItemMeta(itemMeta);
                                int a = Bindenchant.globalMap.get(p) - 1;
                                Bindenchant.globalMap.put(p, a);
                                p.sendMessage(ChatColor.GREEN + "Your item has been successfully repaired! Your remaining credit is " + a + ".");
                            }


                        } else if (Bindenchant.globalMap.get(p) == 0) {
                            event.setCancelled(true);
                            p.sendMessage(ChatColor.DARK_RED + "You cannot repair what gods have forged.");

                        }
                    } else if ((firstSlot.getEnchantmentLevel(Enchantment.DAMAGE_ALL) > 5
                            || firstSlot.getEnchantmentLevel(Enchantment.PROTECTION_ENVIRONMENTAL) > 4
                            || firstSlot.getEnchantmentLevel(Enchantment.DIG_SPEED) > 5
                            || firstSlot.getEnchantmentLevel(Enchantment.ARROW_DAMAGE) > 5) && secondSlot.getType() == Material.ENCHANTED_BOOK
                    ) {
                        event.setCancelled(true);
                        p.sendMessage(ChatColor.DARK_RED + "You cannot enchant what gods forge");

                    }
                }

            }

        }
    }




     

    So now it looks like this, but it just turns to vanilla rename. Whats wrong?
     
  13. What you did wrong is you didn’t change result item at all.
    Learning on spigot isn’t bad or anything and I don’t mean to sound impolite, but I don’t think you know what you’re doing and you may find yourself getting really frustrated on problems that are simple due to a lack of foundational logic.
    I suggest taking a week to do all the Java stuff on here: https://www.w3schools.com/java/default.asp. Make sure you understand it all very well. Think of it as a 1 step backward, 50 steps forward in terms of progression in the future when developing plugins since it will take a little while to click but once it does you can do these problems much more rapidly.

    In the morning, I can spoon feed it to you, but you’re going to keep getting stuck at places like these in the future.

    If you want to give it another shot regardless, create this variable and see if you can get it to work with that specifically:
    String newName = ChatColor.AQUA + resultItem;

    Once you get that working, all you need to do is replace ChatColor.AQUA with a variable that is determined by the if statement I posted earlier.
     
  14. Sorry. I thought the bit on the InventoryClickEvent changed the Item Meta with result.setItemMeta(itemMeta);. If it doesn't, you're right. I don't know what I'm doing.
     
  15. Code (Text):
        @EventHandler
        public void onPrepareAnvil(PrepareAnvilEvent event) {
           
            //Get item in first slot
            ItemStack firstSlot = event.getInventory().getItem(0);
           
            //Get resulting item of inventory
            ItemStack resultItem = event.getResult();
           
           
           
            //Check if resulting item is valid (you should probably also do this for firstSlot)
            if(resultItem.getType() != Material.AIR && resultItem.hasItemMeta()) {
                ItemMeta meta = resultItem.getItemMeta();
                String grabString = firstSlot.getItemMeta().getDisplayName();
                String[] colors = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
                for (String color : colors) {
                     if (grabString.contains("§"+color)) {
                         meta.setDisplayName("§"+color+meta.getDisplayName().substring(1));
                         resultItem.setItemMeta(meta);
                         //Set the resulting item
                         event.setResult(resultItem);
                     }
                }
    Here, try this. It should work just fine. I didn't get a chance to proofread since I have to leave rn, but lmk if you have any problems or if it works good for you.
     
  16. if (grabString.contains("§"+color)) should be if (grabString.contains("&"+color))
     
  17. this results in the rename being correct for a split second (i'm assuming one tick) and reverting back to the bad state. The code looks like this currently.

    Code (Java):


    public class Anvil implements Listener {


        @EventHandler
        public void onPrepareAnvil(PrepareAnvilEvent event) {

            //Get item in first slot
            ItemStack firstSlot = event.getInventory().getItem(0);
            ItemStack secondSlot = event.getInventory().getItem(1);

            //Get resulting item of inventory
            ItemStack resultItem = event.getResult();
         if (firstSlot != null && secondSlot != null){
             if (firstSlot.containsEnchantment(Enchantment.DAMAGE_ALL) || firstSlot.containsEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL) || firstSlot.containsEnchantment(Enchantment.ARROW_DAMAGE) || firstSlot.containsEnchantment(Enchantment.DIG_SPEED)){
                 if ((firstSlot.getEnchantmentLevel(Enchantment.DAMAGE_ALL) > 5
                         || firstSlot.getEnchantmentLevel(Enchantment.PROTECTION_ENVIRONMENTAL) > 4
                         || firstSlot.getEnchantmentLevel(Enchantment.DIG_SPEED) > 5
                         || firstSlot.getEnchantmentLevel(Enchantment.ARROW_DAMAGE) > 5)) {


                     //Check if resulting item is valid (you should probably also do this for firstSlot)
                     if (resultItem.getType() != Material.AIR && resultItem.hasItemMeta()) {
                         ItemMeta meta = resultItem.getItemMeta();
                         String grabString = firstSlot.getItemMeta().getDisplayName();
                         String[] colors = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
                         for (String color : colors) {
                             if (grabString.contains("&" + color)) {
                                 meta.setDisplayName("§" + color + meta.getDisplayName().substring(1));
                                 resultItem.setItemMeta(meta);
                                 //Set the resulting item
                                 event.setResult(resultItem);
                             }
                         }
                     }
                 } else if (secondSlot.getType() == Material.ENCHANTED_BOOK){
                     ItemStack Air = new ItemStack(Material.AIR);

                     event.setResult(Air);


                 }

             }



         }

        }

        @EventHandler
        public void InventoryClick(InventoryClickEvent e) {
            ItemStack firstSlot = e.getInventory().getItem(0);
            Player p = (Player) e.getWhoClicked();
            if (e.getInventory().getType() == InventoryType.ANVIL){
                if (e.getRawSlot() == 2) {
                    if ((firstSlot.getEnchantmentLevel(Enchantment.DAMAGE_ALL) > 5
                            || firstSlot.getEnchantmentLevel(Enchantment.PROTECTION_ENVIRONMENTAL) > 4
                            || firstSlot.getEnchantmentLevel(Enchantment.DIG_SPEED) > 5
                            || firstSlot.getEnchantmentLevel(Enchantment.ARROW_DAMAGE) > 5)) {
                        if (Bindenchant.globalMap.get(p) == null) {
                            e.setCancelled(true);
                            p.sendMessage(ChatColor.DARK_RED + "You don't even have repair credit? Cringe.");
                        } else if (Bindenchant.globalMap.get(p) > 0) {
                            int a = Bindenchant.globalMap.get(p) - 1;
                            Bindenchant.globalMap.put(p, a);
                            p.sendMessage(ChatColor.GREEN + "You have successfully repaired the item. your current credit is " + a + ".");
                        } else if (Bindenchant.globalMap.get(p) == 0) {
                            e.setCancelled(true);
                            p.sendMessage(ChatColor.DARK_RED + "You do not have any repair credit!");
                        }


                    }
                }
            }

        }

    }




     
     
  18. I suggest you use this method :
    Code (Text):

    public static String colorize(String string) {
            if (string == null)
                return null;

            return string.replaceAll("&([0-9a-z])", "§$1");
        }
     

    EDIT: you grabbed the first item name, which is incorrect, the correct code would be:
    Code (Text):

    if (resultItem.getType() != Material.AIR && resultItem.hasItemMeta()) {
                         ItemMeta meta = resultItem.getItemMeta();
                         String grabString = meta.getDisplayName();
                             if (grabString.contains("&([0-9a-z])")) {
                                 meta.setDisplayName(grabString.replaceAll("&([0-9a-z])", "§$1"));
                                 resultItem.setItemMeta(meta);
                             }
    //Set the resulting item
                                 event.setResult(resultItem);

                     }