Solved Getting Item Durability

Discussion in 'Plugin Development' started by dayofdarkfire, Sep 27, 2012.

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

    dayofdarkfire

    I am attempting to make an item return an amount of ingots depending on it's durability. This method seems to work but only if the durability is 100%.

    At 100%, I will get 5 ingots from smelting a helmet. If the item is damaged at all I get 2 ingots. I do have a config file which initially sets the amount of ingots to 2 but I'm not sure why that would conflict with the code. The logic seems fine to me but maybe someone else can spot the issue.

    conifg example ...

    Code:
    IronHelmet:
        ingots: 2
    Code ...

    Code:
      @EventHandler
      public void onFurnaceSmeltEvent(FurnaceSmeltEvent e) {
          ItemStack item = e.getSource();
          int max = item.getType().getMaxDurability();
          int uses = e.getSource().getDurability();
          int percent = 100 - (uses / max * 100);
       
          ItemStack IronHelmet = new ItemStack(Material.IRON_HELMET);
       
          if (item.equals(IronHelmet)){
              int amount = 5;
           
              if (percent >= 75)
                  e.setResult(new ItemStack(Material.IRON_INGOT, amount));
              else if (percent >= 50){
                  amount = 4;
                  e.setResult(new ItemStack(Material.IRON_INGOT, amount));
              }
              else if (percent >= 25){
                  amount = 3;
                  e.setResult(new ItemStack(Material.IRON_INGOT, amount));
              }
              else if (percent > 0){
                  amount = 2;
                  e.setResult(new ItemStack(Material.IRON_INGOT, amount));
              }
          }
      }
    Eventually I will be using this for multiple items and I'd rather not copy and paste this for each item. I tried to write an algorithm to detect what material should be returned in the result but that just failed.
     
  2. Offline

    andf54

    Try (new Double(uses) / new Double(max))

    Or (100.0 * uses / max)
     
  3. Offline

    dayofdarkfire

    Wouldn't that give me the the percent durability used rather than what is left?

    ex. uses = 25; max = 166;

    100 * 25/166 = 15

    [Edit] Oh wait... durability is subtracted from the total isn't it.... so uses would be 141. Is that right?
     
  4. Offline

    andf54

    Sry if I wasn’t clear enough.
    Not sure why you are getting 2, but there are two problems.

    1) item.equals(IronHelmet) change to item.getType() == IRON_HELMET;
    Otherwise equals() would return always return false if damaged, because item with 7 durability does not equal the same item with 34 durability
    same thing with enchantments

    2) change int percent = 100 - (uses / max * 100); to int percent = 100 - (100.0 * uses / max);
    uses / max would always be zero, because it is rounded to a int
    I would suggest you use double percent and ignore the *100
     
  5. Offline

    dayofdarkfire

    Right. That makes a lot of sense. If item.equals(Material.IRON_HELMET) it would be looking for a helmet at full durability. uses / max would be a decimal which, because it's an int type, truncates the decimal to an integer of 0.

    (I'm just re stating what you said to make sure I understand it correctly)

    That should fix it up. Thanks for the help!
     
  6. Offline

    andf54

    Just in case: you meant item.equals(IronHelmet) not item.equals(Material.IRON_HELMET).
    But yeah, that is what I meant.

    In other words: equals() checks everything (ench, dur etc), not just item type.

    I don’t know if it is just me, but I always use 1.0 as 100%. It makes sense, because you want it to be a double anyway. And it is easier to do operations: newAmount = amount * percent, instead of newAmount = amount * percent / 100. Just a tip.

    Also, when you get your code working, add [SOLVED] to your title. Tag me if you need a reply.
     
  7. Offline

    dayofdarkfire

    andf54 Okay so my code is cleaned up a bit now thanks to your suggestions but now I'm receiving a null pointer exception. Here is what I've got:

    Code:
      @EventHandler
      public void onFurnaceSmeltEvent(FurnaceSmeltEvent e) {
          ItemStack item = e.getSource();
          double max = item.getType().getMaxDurability();
          double uses = e.getSource().getDurability();
          double percent = uses/max;
     
          if (item.getType() == Material.IRON_HELMET){
          int amount = getConfig().getInt("IronHelmet.ingots");
          int newAmount = (int) (amount * percent);
     
          e.setResult(new ItemStack(Material.IRON_INGOT, newAmount));
          }
      }
    
     
  8. Offline

    andf54

    Where it points to?

    I'm guessing getConfig().getInt("IronHelmet.ingots"); is null;

    Also, make sure the amount return is correct or you will have an exploit. Pickaxe = 3 iron, shovel = 1 iron etc.

    I dont think the amount of iron required for forging items will change so it is ok to hard code the amounts.

    Or you can do something like if(getConfig().getInt("IronHelmet.ingots") == null{amount = getAmount(item)} else { amount = getConfig().getInt("IronHelmet.ingots")}
     
  9. Offline

    dayofdarkfire

    andf54
    Here is the stack trace:

    Code:
    14:05:55 [WARNING] Failed to handle packet: java.lang.NullPointerException
    java.lang.NullPointerException
            at net.minecraft.server.SlotFurnaceResult.c(SourceFile:49)
            at net.minecraft.server.SlotFurnaceResult.b(SourceFile:37)
            at net.minecraft.server.Container.clickItem(Container.java:201)
            at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:1115)
            at net.minecraft.server.Packet102WindowClick.handle(SourceFile:29)
            at net.minecraft.server.NetworkManager.b(NetworkManager.java:276)
            at net.minecraft.server.NetServerHandler.d(NetServerHandler.java:109)
            at net.minecraft.server.ServerConnection.b(SourceFile:35)
            at net.minecraft.server.DedicatedServerConnection.b(SourceFile:30)
            at net.minecraft.server.MinecraftServer.q(MinecraftServer.java:578)
            at net.minecraft.server.DedicatedServer.q(DedicatedServer.java:213)
            at net.minecraft.server.MinecraftServer.p(MinecraftServer.java:474)
            at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:406)
            at net.minecraft.server.ThreadServerApplication.run(SourceFile:539)
    >
    There isn't a line number for me to check and I see it has to do with the result. I tried to hardcode the amounts in.

    Code:
      @EventHandler
      public void onFurnaceSmeltEvent(FurnaceSmeltEvent e) {
          ItemStack item = e.getSource();
          double max = item.getType().getMaxDurability();
          double uses = item.getDurability();
          double percent = uses/max;
         
          if (item.getType() == Material.IRON_HELMET){
              int amount = 5;
              int newAmount = (int) (amount * percent);
             
              e.setResult(new ItemStack(Material.IRON_INGOT, newAmount));
          }
      }
    From what I can see, I believe that the variable "percent" is somehow always amounting to 0. I tried this:

    int newAmount = (int) (amount * percent) + 1;

    This gave me back 1 ingot.

    The only option I can think of is that the arithmetic is wrong. Correct me if I'm wrong. An iron helmet has a durability of 166. Assuming the item is at full durability item.getType().getMaxDurability will return 166, item.getDurability() will return 166. "percent" (uses/max) 166/166 = 1, yet I get a null pointer exception.

    Okay I got it. item.getDurability() returns 0 if the item is at full durability it works perfectly fine now.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 28, 2016
Thread Status:
Not open for further replies.

Share This Page