How to remove 1 duarbility per PlayerInteractEvent

Discussion in 'Spigot Plugin Development' started by Th3Wh1teG0d, Jan 7, 2020.

  1. Hello, im working on a gun with reload. But i dont know to to remove 1 duarbility per Event.

    now my question is how do i can remove 1 Duarbility per event?

    player.getInventory().getItemInHand().setDurability((-1 every time);
     
  2. I would not ignore Deprecated annotations. There is a reason why they are there. Durability methods are deprecated as you can see here.

    Instead you should get the ItemMeta from the ItemStack and check if it's an instanceof a Damageable. Then cast it to Damageable and use the Damageable#getDamage() and Damageable#setDamage(int damage) methods. Don't forget to set the changed ItemMeta back to the ItemStack.

    To solve your problem just do something like damageable.setDamage(damageable.getDamage() - 1).
     
    • Agree Agree x 1
  3. Code (Java):
    ItemStack stack = new ItemStack(Material.GOLDEN_HOE);
    final Damageable damageable = (Damageable) stack.getItemMeta();
    assert damageable != null;
    damageable.setDamage(damageable.getDamage() - 1);
    stack.setItemMeta(damageable)
    Edit: 1 minute too late, dang
     
    • Like Like x 1
  4. I think I need to explain it more, i want to make a reload feature to my gun and I want that every shot 1 durability gets removed and when the durability is 1 before it break that you can't shoot anymore: you have to reload and when you reload with leftklick then it takes some seconds and the durability goes up to 100%
     
  5. aaaand how does my code and @stonar96's explanation do not help you with this?
    You got everything you need, just apply it!
    You know about events (in this case: PlayerInteractEvent), you know how you set the durability and you know how to get the durability, anything more that you need to know?

    Don't expect us to write all the code for you...
     
  6. ok im sorry but im getting an error

    Could not pass event PlayerInteractEvent to Airsoft v1.0
    org.bukkit.event.EventException: null
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot.jar:git-Spigot-dcd1643-e60fc34]
    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot.jar:git-Spigot-dcd1643-e60fc34]
    at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:500) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:485) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at org.bukkit.craftbukkit.v1_12_R1.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:235) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at org.bukkit.craftbukkit.v1_12_R1.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:202) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at org.bukkit.craftbukkit.v1_12_R1.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:198) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at net.minecraft.server.v1_12_R1.PlayerConnection.a(PlayerConnection.java:991) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at net.minecraft.server.v1_12_R1.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:26) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at net.minecraft.server.v1_12_R1.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:1) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at net.minecraft.server.v1_12_R1.PlayerConnectionUtils$1.run(SourceFile:13) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_231]
    at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_231]
    at net.minecraft.server.v1_12_R1.SystemUtils.a(SourceFile:46) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at net.minecraft.server.v1_12_R1.MinecraftServer.D(MinecraftServer.java:748) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at net.minecraft.server.v1_12_R1.DedicatedServer.D(DedicatedServer.java:406) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at net.minecraft.server.v1_12_R1.MinecraftServer.C(MinecraftServer.java:679) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:577) [spigot.jar:git-Spigot-dcd1643-e60fc34]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_231]
    Caused by: java.lang.ClassCastException: org.bukkit.craftbukkit.v1_12_R1.inventory.CraftMetaItem cannot be cast to org.bukkit.entity.Damageable
    at de.th3wh1teg0d.guns.Weapon.onInteract(Weapon.java:50) ~[?:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_231]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_231]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_231]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_231]
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:302) ~[spigot.jar:git-Spigot-dcd1643-e60fc34]
    ... 18 more

    Code (Java):
     
                                ItemStack stack = new ItemStack(WeaponHandler.Pistole.getMaterial());
                                final Damageable damageable = (Damageable) stack.getItemMeta();
                                assert damageable != null;
                                if(((EntityDamageEvent) damageable).getDamage()<=0){
                                    ((EntityDamageEvent) damageable).setDamage(((EntityDamageEvent) damageable).getDamage() - 1);
     
  7. There are 2 Damageable Interfaces, you want the one from org.bukkit.inventory.meta, and imported the one from org.bukkit.entity.

    I gotta admit, Bukkit can make it really hard sometimes...
    Oh and also please wrap your stack traces inside a code for better readability
     
  8. Im still leraning java and dont know how to fix it
     
  9. on the very top, you have a little statement that reads

    Code (Java):
    import org.bukkit.entity.Damageable;
    probably you have an IDE that has automatically imported that for you (maybe you need to expand that by clicking those little - buttons on the left)

    You want to change that so it reads

    Code (Java):
    import org.bukkit.inventory.meta.Damageable;
     
  10. it turns red and says: The import org.bukkit.inventory.meta.Damageable cannot be resolved
     
  11. Why are you suggesting to use assert?

    Please read your error.
    And please don't do this, simply use an if check.

    I'll try my best to explain it to you:

    Code (Java):
    final Damageable damageable = (Damageable) stack.getItemMeta();
    Before this, I'd recommend checking if the item's ItemMeta is an instance of Damageable, like so:
    Code (Java):
    if (stack.getItemMeta() instanceof Damageable)
    If this returns false, the item doesn't use durability.
    If this returns true however, you want to reduce the durability, I assume.

    Now would be a good moment to create the damageable variable. Paste it in and set that same variable's damage to ItemMeta#getDamage() - 1.
    If you've done this properly, you won't need this line:
    Code (Java):
    if (((EntityDamageEvent) damageable).getDamage() <= 0) {
    Instead, replace it with something more friendly:
    Code (Java):
    if (damageable.getDamage() <= 0)
    Make sure you imported the right Damageable (check your imports). You want org.bukkit.inventory.meta, not org.bukkit.entity:
    upload_2020-1-7_22-25-57.png

    Then after all this, don't forget to set the item's ItemMeta to the updated ItemMeta, as that's the one that holds the damage data, remember?
    To do so, we call:
    Code (Java):
    stack.setItemMeta(damageable);
    That's all!
     
    • Useful Useful x 1
  12. assert: ItemMeta should never return null for this Stack, if the assertion fails something is going massively wrong and you know where it is
    Instance check: You don't need that. Suppose:

    Code (Java):
    class Vehicle {}

    class Car extends Vehicle {}

    main() {
       Vecicly myVehicle = new Car();
        Car myCar = (Car) myVehicle;
    }
    is basically the same as casting your ItemMeta to damageable since this is how it is instantiated.

    other than that, nicely explained
     
    • Friendly Friendly x 1
  13. So... This is my full code for this

    Code (Java):
     
    public class Weapon implements Listener {
         
        private HashMap<UUID, Long> cd = new HashMap<UUID, Long>();
        public static Plugin plugin;
       
        @SuppressWarnings("static-access")
        public Weapon(Plugin plugin){
                this.plugin = plugin;
        }
       
        @SuppressWarnings("deprecation")
        @EventHandler
        public void onInteract(PlayerInteractEvent event){
            Player player = (Player)event.getPlayer();          
            if(cd.containsKey(player.getUniqueId()) && cd.get(player.getUniqueId()) > System.currentTimeMillis()) {
                event.setCancelled(true);
               
            } else if(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK){
                final ItemStack itemInHand = player.getItemInHand();
                if (itemInHand.getType() == WeaponHandler.Pistole.getMaterial()) {
                    final ItemMeta meta = itemInHand.getItemMeta();
                    if (meta != null) {
                        if (meta.hasDisplayName()) {
                            final String dn = meta.getDisplayName();
                            if (dn.equals("§8«§9Walther P99§8»")) {
                                Snowball snowball = player.getWorld().spawn(player.getEyeLocation(), Snowball.class);
                                snowball.setVelocity(player.getLocation().getDirection().multiply(3));
                                snowball.setShooter(player);
                                player.getWorld().playSound(player.getLocation(), WeaponHandler.Pistole.getSound(), 10, 10);
                               
                                    ItemStack stack = new ItemStack(WeaponHandler.Pistole.getMaterial());
                                    if (stack.getItemMeta() instanceof Damageable) {
                                        final Damageable damageable = (Damageable) stack.getItemMeta();
                                        if (damageable != null) {
                                            if (((*EntityDamageEvent) damageable).getDamage() <= 0) {
                                            ((*EntityDamageEvent) damageable).setDamage(((*EntityDamageEvent) damageable).getDamage() - 1);
                                            stack.setItemMeta(**ItemMeta) damageable);
                                            }
                                        }
                                    }
                                }
                                cd.put(player.getUniqueId(), System.currentTimeMillis() + (1 * 500));
                            }
                        }
                    }
                }
           
            if(event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK){
                final ItemStack itemInHand2 = player.getItemInHand();
                if (itemInHand2.getType() == WeaponHandler.Pistole.getMaterial()) {
                    final ItemMeta meta2 = itemInHand2.getItemMeta();
                    if (meta2 != null) {
                        if (meta2.hasDisplayName()) {
                            final String dn2 = meta2.getDisplayName();
                            if (dn2.equals("§8«§9Walther P99§8»")) {
                            }
                        }
                    }
                }
            }
        }

        @SuppressWarnings("deprecation")
        @EventHandler
        public void onHit(EntityDamageByEntityEvent event){
            if(event.getDamager() instanceof Snowball){
                Snowball snowball = (Snowball)event.getDamager();
                Player shooter = (Player)snowball.getShooter();
                if(shooter.getItemInHand().getType() == WeaponHandler.Pistole.getMaterial()){
                    event.setDamage(WeaponHandler.Pistole.getDamage());
                }
            }
        }
    }
     
    When im not using * or ** (* = look in the code)

    it says

    * = The method getDamage() is undefined for the type Damageable

    ** = The method setItemMeta(ItemMeta) in the type ItemStack is not applicable for the arguments (Damageable)

    so also when im trying to import
    import org.bukkit.inventory.meta.Damageable;

    it says : The import org.bukkit.inventory.meta.Damageable cannot be resolved

    now it isnt making any errors but the item dosent get the -1 duarbility.

    Info:

    Im Using Eclipse and 1.12.2
     
  14. Why don't y'all just update to 1.15.1
    but since I can't force anyone to, use item.setDurability(int) and item.getDurability() instead of the meta and you should be good to go

    ...
     
    • Agree Agree x 1
  15. I like using the 1.12.2 but what do i have to do now ?
     
  16. what I have written. Instead of using the ItemMeta, use item.setDurability(int) and item.getDurability()
     
  17. Replace item with stack in your case.
     
  18. When I say item, I meant what you have saved as variable "stack"
    should have been clearer, sry
     
  19. So when im trying this:
    Code (Java):

        @SuppressWarnings("deprecation")
        @EventHandler
        public void onInteract(PlayerInteractEvent event){
            Player player = (Player)event.getPlayer();          
            if(cd.containsKey(player.getUniqueId()) && cd.get(player.getUniqueId()) > System.currentTimeMillis()) {
                event.setCancelled(true);
             
            } else if(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK){
                final ItemStack itemInHand = player.getItemInHand();
                if (itemInHand.getType() == WeaponHandler.Pistole.getMaterial()) {
                    final ItemMeta meta = itemInHand.getItemMeta();
                    if (meta != null) {
                        if (meta.hasDisplayName()) {
                            final String dn = meta.getDisplayName();
                            if (dn.equals("§8«§9Walther P99§8»")) {
                                Snowball snowball = player.getWorld().spawn(player.getEyeLocation(), Snowball.class);
                                snowball.setVelocity(player.getLocation().getDirection().multiply(3));
                                snowball.setShooter(player);
                                player.getWorld().playSound(player.getLocation(), WeaponHandler.Pistole.getSound(), 10, 10);
                             
                                if (itemInHand.getDurability() <= 0) {
                                    itemInHand.setDurability((short) -1);
                                 
                                }
                            }
                            cd.put(player.getUniqueId(), System.currentTimeMillis() + (1 * 500));
                        }
                    }
                }
            }
     
    no errors but nothing in the Durability change. :/