Why is the inventory updating?

329 views Asked by At

I am using Bukkit API 1.8 with Java 7.

I have a repeating task that loops through all the players on the server and sets their armor randomly to either leather, chainmail, etc...

When I use the method setHelmet,setChestplate, etc... I update their inventory like usual, but since this task is running every 6 ticks, it runs fast. Therefore, when a player tries to fire a bow, the bow resets its power every time this task runs.

Since I knew it was a problem with updating the inventory, I tried removing the updateInventory method.

After doing this the armor still got put on and changed, but the bow was still being reset every time the task was ran.

How would I keep the bow from resetting while still keeping the task running?

My code:

@SuppressWarnings("deprecation")
public static void repeatEffect()
{
    main.getServer().getScheduler().scheduleAsyncRepeatingTask(main, new Runnable()
    {
    @Override
        public void run()
        {
          for(Player o : Bukkit.getOnlinePlayers())
          {
            Material M1 = Material.WOOL;
            int num = rainbow.get(o.getName());
            if(num==1)
            {
               M1 = Material.LEATHER_HELMET;
            }
            else if(num==2)
            {
               M1 = Material.CHAINMAIL_HELMET;
            }
            else if(num==3)
            {
               M1 = Material.GOLD_HELMET;
            }
            else if(num==4)
            {
               M1 = Material.IRON_HELMET;
            }
            else if(num==5)
            {
               M1 = Material.DIAMOND_HELMET;
            }
            rainbow.put(o.getName(), num+1);
            if(rainbow.get(o.getName())>5)
            {
               rainbow.put(o.getName(), 1);
            }
            ItemStack rrhelm = createItemStack(M1, 1, "§a§lR§b§la§c§li§d§ln§e§lb§f§lo§a§lw §c§lH§d§le§e§ll§f§lm§a§le§b§lt", "§7Very special piece of armor");
            o.getInventory().setHelmet(rrhelm);
          }
        }
    }
    , 6, 6);
}
2

There are 2 answers

0
Pieter12345 On

If changing armour resets the players bow, you could work around it by only changing the armour of players who are joining, not wielding a bow or just after an EntityShootBowEvent.

To see if the player is wielding a bow, use:

org.bukkit.Bukkit.entity.Player player = ...;
boolean hasBowEquiped = player.getEquipment().getItemInHand().getData().getItemType().equals(Material.BOW);
2
Adrian Sohn On

After testing this some more, the only way I was able to reproduce the bow complication was by calling the deprecated updateInventory() method which you said you removed. I'm fairly certain that you still have this method somewhere in your code because I can't find anything else that would cause the bow to act this way (I was still able to fire the bow but the animation looks glitchy and the power of the arrow is sometimes incorrect).

The only difference between my code is that I used new ItemStack(M1) instead of your createItemStack() method to instantiate the helmet (also tried changing name, lore and amount). I was still able to shoot a bow just fine. Could the resetting of the bow/inventory have something to do with your createItemStack method?

There's no reason why you should be running this task asynchronously. You're accessing the Bukkit API from an asynchronous task or different thread which is a big no-no and can cause all kinds of tricky problems. Use the scheduleSyncRepeatingTask method to run the task in the same thread.

For simplicity's sake I randomly set a single armor slot (also tried all four) to either leather or iron every 6 ticks. Didn't seem to interfere with the bow. Could we see your code? Here is mine:

public void onEnable() {
    this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
        public void run() {
            for (World world : Bukkit.getWorlds()) {
                for (Player player : world.getPlayers()) {
                    if (Math.random() < 0.5) {
                        player.getInventory().setBoots(new ItemStack(Material.IRON_BOOTS));
                    } else {
                        player.getInventory().setBoots(new ItemStack(Material.LEATHER_BOOTS));
                    }
                }
            }
        }
    }, 0, 6);
}