Bukkit Runnable on ItemStacks

Discussion in 'Plugin Development' started by Zacky1, Aug 11, 2014.

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

    Zacky1

    Hi everyone.

    I'm trying to add a bukkit run task later on an Item Stack yet the modifications made during the run task later isn't achieved yet it is called.

    Code:
    final ItemStack itemStack = player.getItemInHand();
    Bukkit.getScheduler().runTaskLater(Main.instance, new Runnable() {
                public void run() {
                    ItemMeta im = itemStack.getItemMeta();
                    List<String> ls = im.getLore();
                    //Do stuff
                    im.setLore(ls);
                    itemStack.setItemMeta(im);
                }
            }, 50L);
    So ya. This method is called yet the lore is never cleared. Anyone got any ideas as to how I can make it work?
     
  2. Offline

    stormneo7

    Code:java
    1. List<String> ls = im.getLore();
    2. //Do stuff
    3. im.setLore(ls);

    I really don't get it. You want to set the item's lore to it's lore.
     
  3. Offline

    Zacky1


    I do stuff with the lore then set it back. Thats why its commented out.
     
  4. Offline

    hintss

    Are you setting the itemstack in the inv back to the new itemstack?
     
  5. Offline

    stormneo7

    Why is that being withdrawn? Show me what you did with the lore.
     
  6. Offline

    Zacky1


    Code:
    ls.add("This item is loading");
    But isn't the itemstack just a reference, wouldn't it update in the inventory?
     
  7. Offline

    stormneo7

    Code:
    ls.clear();
    Alright so what I'm about to say might not be accurate.
    1. Since you are working with a scheduler and the ItemStack is defined outside of it, it might be best that you clone() the ItemStack.
    2. p.setItemInHand(ItemStack);
     
  8. Offline

    MCForger

    stormneo7 Zacky1
    Do not use the clone method. Instead use the copy constructor for ItemStack. Also you can make your own class the extends BukkitRunnable and you pass a player object through the constructor. Then on run check to make sure the player is online and the item in hand is not null. Once those are checked modify the lore and set the new itemmeta to the ItemStack.
     
  9. Offline

    Zacky1


    The problem with setItemInHand is that the task is ran 10 seconds later. In 10 seconds of course he would've changed item slot. Thus setItemInHand would not be the item I need. And keeping track of where that item went isn't what I want.

    I think a way to make Bukkit Task work with it would be the golden thing to happen..
     
  10. Offline

    stormneo7

    No such thing as a copy constructor.

    There's no function in the current bukkit api that I'm aware of that does that.
    1. Player can move the ItemStack to crafting / chest.
    2. Player can drop the ItemStack in which the ItemStack turns into an Item.
    3. ItemStack could be at a player's cursor.

    Obviously you could track all the processes done to the ItemStack and modify it there but that's quite a lot of work.
     
  11. Offline

    Zacky1

    Yet some servers are able to do just this. I.e. WynnCraft is able to do it. Not sure how, however I do know it works...
     
  12. Offline

    MCForger

  13. Offline

    Necrodoom

    stormneo7 I'm assuming that by copy constructor he means new ItemStack(ItemStack is) constructor.
     
  14. Offline

    MCForger

    Necrodoom
    Yes, that is a copy constructor.
     
  15. Offline

    stormneo7

    MCForger

    How is that better or more preferred than .clone()...
     
  16. Offline

    Zacky1

    Upon further investigation, I created a custom repeating task. And my run methodlooks like this:

    Code:java
    1. i--;
    2. Bukkit.broadcastMessage("ran part 1");
    3. ItemMeta im = itemStack.getItemMeta();
    4. String s = im.getLore().get(0);
    5. List<String> ls = new ArrayList<String>();
    6. ls.add(s);
    7. ls.add("");
    8. if(i > 0) {
    9. Bukkit.broadcastMessage("ran part 2 sleft"+i);
    10. ls.set(1, ""+i);
    11. im.setLore(ls);
    12. itemStack.setItemMeta(im);
    13. }else {
    14. ls.remove(1);
    15. Bukkit.broadcastMessage("ran part 3");
    16. im.setLore(ls);
    17. itemStack.setItemMeta(im);
    18. this.cancel();
    19. }


    The debug gives the right thing:
    ran part 1
    ran part 2 sleft2
    ran part 1
    ran part 2 sleft1
    ran part 1
    ran part 3

    However the item stack is not updated. Anyone got any ideas?
     
  17. Offline

    chaseoes Retired Staff

    Are you adding it to the inventory?
     
    hintss likes this.
  18. Offline

    Zacky1

    Heres the thing: I don't want to follow the item stack for 5 minutes... So my question is: Why is the reference not working in bukkit runnables.

    In a single method you can edit the itemstack ect. and have it work. However as soon as you pass the item stack into a runnable or task it doesn't work but the itemstack is never cloned/copied only passed.

    Anyone know why and a way around it?
     
  19. Offline

    chaseoes Retired Staff

    As far as I know that only works up until the point it's added to an inventory? You can't modify an item already in the inventory.
     
  20. Offline

    Zacky1


    Then why does this work?
    Code:java
    1.  
    2. public void onRightClick(){
    3. final ItemStack is = mplayer.getPlayer().getItemInHand();
    4. ItemMeta im = is.getItemMeta();
    5. im.setDisplayName("Hi");
    6. is.setItemMeta(im); //Up until this point it works!
    7.  
    8. //This point forth nothing works..
    9. Bukkit.getScheduler().scheduleSyncRepeatingTask(MCMain.instance, new Runnable() {
    10. public void run() {
    11. ItemMeta im = is.getItemMeta();
    12. im.setDisplayName("SUP MATE");
    13. is.setItemMeta(im);
    14. Bukkit.broadcastMessage("ran");
    15. }
    16. }, 0, 20L);
    17. }
     
  21. Offline

    xTigerRebornx

    Zacky1 Question, have you tried updating the Inventory of the Player after setting it in the delayed task?
     
  22. Offline

    Zacky1


    Yes, it doesn't do anything.
     
  23. Offline

    chaseoes Retired Staff

    It doesn't work, you said so yourself in a comment right before the task.
     
  24. Offline

    Zacky1

    Im saying the task doesn't work, but before the task it does. Now apparently we cant do this. Why? No idea.
     
  25. Offline

    Zacky1

  26. Offline

    fireblast709

    Zacky1 try getting the ItemStack he holds every run (so a new player.getItemInHand() inside the runnable as well)
     
  27. Offline

    Zacky1

    fireblast709 that works, but that's besides the point... I want to know if its possible to create a repeating task that has the item stack. If I set that repeating task to repeat for 5 minutes, I don't want to follow the item stack everywhere and update the task..

    Why is the reference not working in tasks?

    Upon even further investigation ive come up with this:
    Code:java
    1. @Override
    2. public void run() {
    3. i--;
    4. Bukkit.broadcastMessage("IS: "+itemStack.getType());
    5. itemStack.setType(Material.BEDROCK);
    6. player.updateInventory();
    7. if(i > 0) {
    8. Bukkit.broadcastMessage("ran isc sleft"+i);
    9. ls.set(1, ChatColor.RED+"Exploding in "+i+"s");
    10. im.setLore(ls);
    11. itemStack.setItemMeta(im);
    12. }else {
    13. ls.remove(1);
    14. Bukkit.broadcastMessage("ran isc no secs left");
    15. im.setLore(ls);
    16. itemStack.setItemMeta(im);
    17. this.cancel();
    18. }
    19. }


    This gives the following output:
    IS: BLAZE_ROD
    ran isc sleft500
    IS: BEDROCK
    ran isc sleft499

    Yet the itemstack is never updated in the player's inventory
     
  28. Offline

    fireblast709

    Zacky1 Blame Minecraft and move on?
     
Thread Status:
Not open for further replies.

Share This Page