Solved Getting an item's lore.

Discussion in 'Plugin Help/Development/Requests' started by oceantheskatr, Apr 13, 2015.

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

    oceantheskatr

    Hi, I'm working on a "Wands" plugin. When a player uses a spell, I change the name of the item to the spell name and then back. This is mainly so that the wand only works when it has the name "Frost Wand", instead of it's spell's names like "Blizzard Dash" or "Snowshot". However, if you drop the item right after you use the spell, the name will change and will of course stay the same since there's no wand in your inventory to change back. I've made a "PlayerPickupItemEvent" event so that when a player picks up the wand, if the display name of it is "Blizzard Dash" or "Snowshot", then it will change it back to "Frost Wand".

    My problem is that I'd like to use the item's lore to decide what to rename it to, so that if the lore contains "Wand type: Ice/Snow" then it'll rename it to "Frost Wand".

    TL;DR: How do I check to see if an item's lore contains certain words/text?

    I did attempt to do it myself first, my code is below.

    Also, my lore looks something like this:

    [​IMG]

    Code:
        @EventHandler
        public void onPickup(PlayerPickupItemEvent e) {
            Player player = e.getPlayer();
            Inventory i = player.getInventory();
            for(ItemStack item : i.getContents()) {
                if (item.getType().equals(Material.STICK)) {
                    if (item.hasItemMeta()) {
                        ItemMeta meta = item.getItemMeta();
                        if (meta.hasLore()) {
                            List<String> lore = meta.getLore();
                            if (lore.contains("Ice/Snow")) {
                                item.getItemMeta().setDisplayName("" + ChatColor.AQUA + ChatColor.BOLD + "Frost Wand");
                            }
                            if (lore.contains("Lava/Fire")) {
                                item.getItemMeta().setDisplayName("" + ChatColor.GOLD + ChatColor.BOLD + "Nether Wand");
                            }
                            if (lore.contains("Water")) {
                                item.getItemMeta().setDisplayName("" + ChatColor.BLUE + ChatColor.BOLD + "Water Wand");
                            }
                        }
                    }
                }
            }
        }
    Thank you in advance to anyone who may be able to provide some assistance for me! :)
     
  2. Offline

    Xerox262

    Try meta.setDisplayname() instead of item then set the item meta to meta and then send a e.getPlayer().updateInventory(). That's how I did it:
    Code:
    ItemStack bow = new ItemStack(Material.BOW, 1);
                ItemStack arrows = new ItemStack(Material.ARROW, this.getConfig()
                        .getInt("Arrow amount"));
    
                ItemMeta bowMeta = (ItemMeta) bow.getItemMeta();
    
                bowMeta.setDisplayName(getConfig().getString("Bow name")
                        .replaceAll("&", "ยง").replaceAll("%p", player.getName())
                        .replaceAll("%n", player.getDisplayName()));
    
                bow.setItemMeta(bowMeta);
    
                player.getInventory().setItem(getConfig().getInt("Bow slot") - 1, bow);
                player.getInventory().setItem(getConfig().getInt("Arrow slot") - 1, arrows);
                player.updateInventory();
                return;
    
     
  3. Offline

    oceantheskatr

    @Xerox262 Thank you for your reply! :)

    Not sure where I'd do this ^

    Here is my updated code:
    Code:
        @EventHandler
        public void onPickup(PlayerPickupItemEvent e) {
            Player player = e.getPlayer();
            Inventory i = player.getInventory();
            for(ItemStack item : i.getContents()) {
                if (item.getType().equals(Material.STICK)) {
                    if (item.hasItemMeta()) {
                        ItemMeta meta = item.getItemMeta();
                        if (meta.hasLore()) {
                            List<String> lore = meta.getLore();
                            if (lore.contains("Ice/Snow")) {
                                meta.setDisplayName("" + ChatColor.AQUA + ChatColor.BOLD + "Frost Wand");
                                player.updateInventory();
                            }
                            if (lore.contains("Lava/Fire")) {
                                meta.setDisplayName("" + ChatColor.GOLD + ChatColor.BOLD + "Nether Wand");
                                player.updateInventory();
                            }
                            if (lore.contains("Water")) {
                                meta.setDisplayName("" + ChatColor.BLUE + ChatColor.BOLD + "Water Wand");
                                player.updateInventory();
                            }
                        }
                    }
                }
            }
        }
    When I pick up an item, I do however get this error in my console: http://hastebin.com/qeduxahimu.avrasm
     
    Last edited: Apr 13, 2015
  4. Offline

    Neilnet

    Code:
    Caused by: java.lang.NullPointerException     at me.themineshack.GetLore.onPickup(GetLore.java:39) ~[?:?]
    
    NPE Error: Meaning you're trying to access an item or run a method from an item which is Null (not initialized). It says it's on line 39, in GetLore class.

    Show us that class and the line there.
     
  5. Offline

    oceantheskatr

    @Neilnet


    Code:
    package me.themineshack;
    
    import java.util.List;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerPickupItemEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class GetLore extends JavaPlugin implements Listener {
    
        @Override
        public void onEnable() {
            Bukkit.getServer().getPluginManager().registerEvents(this, this);
        }
    
        @Override
        public void onDisable() {
        
        }
    
    
        @EventHandler
        public void onPickup(PlayerPickupItemEvent e) {
            Player player = e.getPlayer();
            Inventory i = player.getInventory();
            for(ItemStack item : i.getContents()) {
                if (item.getType().equals(Material.STICK)) {
                    if (item.hasItemMeta()) {
                        ItemMeta meta = item.getItemMeta();
                        if (meta.hasLore()) {
                            List<String> lore = meta.getLore();
                            if (lore.contains("Ice/Snow")) {
                                meta.setDisplayName("" + ChatColor.AQUA + ChatColor.BOLD + "Frost Wand");
                                player.updateInventory();
                            }
                            if (lore.contains("Lava/Fire")) {
                                meta.setDisplayName("" + ChatColor.GOLD + ChatColor.BOLD + "Nether Wand");
                                player.updateInventory();
                            }
                            if (lore.contains("Water")) {
                                meta.setDisplayName("" + ChatColor.BLUE + ChatColor.BOLD + "Water Wand");
                                player.updateInventory();
                            }
                        }
                    }
                }
            }
        }
    }
    
    Line 39 is if (item.getType().equals(Material.STICK)) {

    Edit: Should it be if (item.getType() == Material.STICK) { ?
     
  6. Offline

    I Al Istannen

    @oceantheskatr So, you want to rename the PICKED UP item, if its Lore contains some words?
    If so you can use e.getItem(). That returns the Item Entity, you can convert it with item.getItemStack().
    Also i would use an enhanced for loop to loop through the String contents of the lore, so your Lore text can be colored or sth else and the program will still say its an Special wand. Also you don't need to use player.updateInventory() but you need to apply the meta to the itemStack with itemStack.setItemMeta(ItemMeta meta).

    And now to your question: Yes, you can use a == operator with Enum values (for Example Material) and you get a NullPointerException (http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it).
     
  7. Offline

    oceantheskatr

    @I Al Istannen alright thank you, I'll work on this later on in the day and send a reply on how it works out :)

    @I Al Istannen I've changed my code a bit to incorporate what you said. I didn't understand all of it, as I am not sure how to use/write an enhanced "for" loop.

    I have also simplified my code a bit specifically for this testing, and then after I learn how to check lore properly I will implement this in my main plugin.

    Code:
        @EventHandler
        public void onPickup(PlayerPickupItemEvent e) {
            Player player = e.getPlayer();
            Inventory i = player.getInventory();
            ItemStack item = e.getItem().getItemStack();
            if (item.getType() == Material.STICK) {
                if (item.getItemMeta().hasLore() == true) {
                    for (String lore : item.getItemMeta().getLore()) {
                        if (lore.contains("test")) {
                            item.getItemMeta().setDisplayName("Not a Stick!");
                          }
                    }
                }
            }
        }
    I am hoping that you may possibly be able to give an example on getting lore, or how I would go about creating an enhanced for loop for this.

    Thank you for your time! :)

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 12, 2016
  8. Offline

    I Al Istannen

    @oceantheskatr You did use an enhanced for loop ;)
    http://stackoverflow.com/questions/11685305/what-is-the-syntax-of-enhanced-for-loop-in-java
    Also you don't need to check for == true:
    Code:
     if (item.getItemMeta().hasLore() == true) {
    
    because the if will continue if it's statement is true.

    As far as i know you can't just set the displayName of the meta, but must create an itemMeta variable from item.getItemMeta() and then modify this.
    Then you have to apply the meta to the itemStack. Use "item.setItemMeta(meta)" for that.
     
  9. Offline

    oceantheskatr

    @I Al Istannen modified code with what you said and it worked!

    Updated code:

    Code:
        @EventHandler
        public void onPickup(PlayerPickupItemEvent e) {
            Player player = e.getPlayer();
            Inventory i = player.getInventory();
            ItemStack item = e.getItem().getItemStack();
            if (item.getType() == Material.STICK) {
                if (item.getItemMeta().hasLore()) {
                    for (String lore : item.getItemMeta().getLore()) {
                        if (lore.contains("test")) {
                            ItemMeta meta = item.getItemMeta();
                            meta.setDisplayName("Not a Stick!");
                            item.setItemMeta(meta);
                          }
                    }
                }
            }
        }
    I will now implement this on my actual code. If it works out (which it should!) then I'll be setting this to solved :)

    Thank you again for your help!
     
  10. Offline

    I Al Istannen

    @oceantheskatr At the base of that code you can delete the "Inventory i =..." :)
    Glad i could help.
     
  11. Offline

    oceantheskatr

    @I Al Istannen All implemented and working!

    Next time I am having an error that I can't figure out myself (via 2 hours of Googling) and am going to be making a post on here, do you mind if I tag you in my post?
     
  12. Offline

    I Al Istannen

    @oceantheskatr I don't mind. It can just take some time till i respond ;) its 7.40 AM after all ;D
     
  13. Offline

    oceantheskatr

    Alright thank you. Late help is much better than no help ;) 1:40am here!
     
Thread Status:
Not open for further replies.

Share This Page