Getting item id and durability from config?

Discussion in 'Plugin Development' started by KarimAKL, Jul 2, 2018.

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

    KarimAKL

    I've been trying to make a config like this:
    Code:
    id: 263:1
    But i can't seem to figure out how i would get it, here is what i've been trying:
    Code:Java
    1. public class PlayerInteract implements Listener {
    2.  
    3. private Main plugin;
    4.  
    5. public PlayerInteract(Main plugin) {
    6. this.plugin = plugin;
    7. Bukkit.getPluginManager().registerEvents(this, plugin);
    8. }
    9.  
    10. @SuppressWarnings("deprecation")
    11. @EventHandler
    12. public void onInteract(PlayerInteractEvent e) {
    13. Player p = e.getPlayer();
    14. if (e.getClickedBlock() != null) {
    15. ItemStack ih = p.getItemInHand();
    16. if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
    17. String[] id = plugin.getConfig().getString("id").split(":");
    18. String item = Material.getMaterial(id[0]).toString().toLowerCase();
    19. if (ih.getTypeId() == Integer.valueOf(id[0]) && ih.getDurability() == Short.valueOf(id[1])) {
    20. //Success! :)
    21. } else {
    22. //Failure.. :(
    23. }
    24. }
    25. }
    26. }
    27. }

    But this hasn't been working because of a NPE at this line:
    Code:Java
    1. String item = Material.getMaterial(id[0]).toString().toLowerCase();


    I know using material id is deprecated and it would be better to use material names instead but for now i'll just use id and focus on getting it working.
     
  2. Offline

    Zombie_Striker

    @KarimAKL
    Use Material names. There is no need to try to support a system that you will need to change.

    First, you should move the config-reading to the constructor, as it should only be done once.

    Then, you should get the material using:
    Code:
    Material item = Material.matchMaterial(id[0]);
    Then, you need to change valueOf to parseShort. Although the numeric values are the same, valueOf returns a new Short, while parseShort returns a primitive 'short', which is what is stored for the durability. So change the last durability check to
     
  3. Offline

    KarimAKL

    @Zombie_Striker
    1. Oh well, guess i'll try to use material names then, where should i start? (I would like to be able to use the in-game names for it instead of the "Material.WHATEVER", maybe i should use "Material.values()"?)
    2. Do you mean something like this?:
    Code:Java
    1. public class PlayerInteract implements Listener {
    2.  
    3. String[] id;
    4.  
    5. private Main plugin;
    6.  
    7. public PlayerInteract(Main plugin) {
    8. this.plugin = plugin;
    9. Bukkit.getPluginManager().registerEvents(this, plugin);
    10. this.id = plugin.getConfig().getString("item").split(":");
    11. }
    12.  
    13. @SuppressWarnings("deprecation")
    14. @EventHandler
    15. public void onInteract(PlayerInteractEvent e) {
    16. Player p = e.getPlayer();
    17. if (e.getClickedBlock() != null) {
    18. ItemStack ih = p.getItemInHand();
    19. if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
    20. String item = Material.getMaterial(id[0]).toString().toLowerCase();
    21. if (ih.getTypeId() == Integer.valueOf(id[0]) && ih.getDurability() == Short.parseShort(id[1])) {
    22. //Success! :)
    23. } else {
    24. //Failure.. :(
    25. }
    26. }
    27. }
    28. }
    29. }

    3. I'll do that when i've changed it to material names instead of id.
    4. I see, i'll change that then, thanks for the information. :)
     
  4. Offline

    Zombie_Striker

    @KarimAKL
    1. In that case, you will need to create a new Hashmap/class that will store the in-game names and link it to the material types (since Bukkit does not store these names)
    2. Sort of. The parsing of the material should also be done in the constructor as well (that way bukkit does not need to loop through all of the material types every time a player right clicks on a block.)
    Also note that you are not doing anything with 'item'. Even through you have the material's name (which you don't need, as you only need the material type) you don't use it and instead try to use the id[0] as an Integer and compare it to the type id (something that cannot possibly happen, since you're treating the id[0] as the material name in the line above; it can't be both a number and a name).

    [Edit] Also, you're using getMaterial instead of matchMaterial. getMaterial is deprecated, as you should be using matchMaterial() since it supports upper and lower case names.
     
  5. Offline

    KarimAKL

    @Zombie_Striker
    1. Would that mean i would have to make a huge list where link every word with the item i want it to be? (Example stone = STONE, bed = BED, etc)
    2. Okay, that would mean i should just make the things in 1(the above line) in the constructor, right?
    3. About the "item" that was because i was planning to do something with that later, tho i haven't done anything with it yet.
    4. What do you mean? I thought that i was getting the id from the string "item"(i changed it to "item" from "id") and then i got what material the id is in lower case as a string with this:
    Code:Java
    1. String item = Material.getMaterial(id[0]).toString().toLowerCase();

    Then i get the integer in id[0] and check if the TypeId of the item in the player's hand is the same as the TypeId in id[0] (not the item name from the line above)
    Is that not what i'm doing? :/ Anyway, that's gonna change when i change it to material names instead of material ids.
    5. Is matchMaterial just getMaterial but it supports upper and lower case names? If that's the case i'll change it right away. :p
     
  6. Offline

    Zombie_Striker

    @KarimAKL
    1. Sort of. This would only need to be done with materials that have different names (e.g. gunpowder is SULPHER in the material names, though this may be changed in 1.13.)
    2. Yes.
    3. k
    4. Yes, but since the value is a String, it will be treated as though you are providning the name. If you need it as an number id (which you don't), you would need to parseInteger to conver it to an int.
    5. Yes.
     
  7. Offline

    KarimAKL

    @Zombie_Striker
    1. Okay, thanks for the information. :)
    2. Okay. :)
    3. :)
    4. Oh, just "parseInt" instead of "valueOf"?
    5. Okay, will do that then. :)
    EDIT: About 1, would something like this work?
    Code:Java
    1. public class PlayerInteract implements Listener {
    2.  
    3. Material name;
    4. String[] id;
    5.  
    6. private Main plugin;
    7.  
    8. public PlayerInteract(Main plugin) {
    9. this.plugin = plugin;
    10. Bukkit.getPluginManager().registerEvents(this, plugin);
    11. this.id = plugin.getConfig().getString("item").split(":");
    12. if (id[0].toLowerCase().equals("gunpowder")) {
    13. this.name = Material.SULPHUR;
    14. }
    15. }
    16.  
    17. @EventHandler
    18. public void onInteract(PlayerInteractEvent e) {
    19. Player p = e.getPlayer();
    20. if (e.getClickedBlock() != null) {
    21. ItemStack ih = p.getItemInHand();
    22. if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
    23. String item = id[0];
    24. if (ih.getType() == name) {
    25. //Success! :)
    26. } else {
    27. //Failure.. :(
    28. }
    29. }
    30. }
    31. }
    32. }

    (In the code i haven't done anything with id[1] yet, just saying)
     
    Last edited by a moderator: Jul 3, 2018
Thread Status:
Not open for further replies.

Share This Page