[Solved] Item amount doesn't get updated (CraftItemEvent)

Discussion in 'Plugin Development' started by attrib, Aug 19, 2012.

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

    attrib

    I'm started working on a Repair Plugin and have bug I need help with.

    If I update the amount of a item in the workbench grid in the CraftItemEvent, the amount doesn't get updated on the client side, till the user picks it up.
    Basicly it breaks down to the following code:
    Code:
    @EventHandler
    public void onCraftItem(CraftItemEvent event) {
      event.getInventory().getItem(3).setAmount(5);   
    }
    
    What I want to reach with this, is a dynamic recipe as the amount of a item needed depends on the durability of the other item inserted. This code works with the flaw the user do not notice the amount change until he clicks on it.
    Currently I think this is a issue with the client, because it do not update the amount display. If so this would mean the only solution would be a spout client plugin, which then updates the amount. Am I right? Or is there another solution in bukkit for such a problem? Some Event I could use or send a update notice to the client?

    My seconds problem is basicly the same I think. The PrepareItemCraftEvent is only get called if bukkit founds a recipe for the current items in the workbench. But it doesn't get called, if the user changes the amount of a item in the workbench grid. What I want to reach here, is the the Result item is getting updated, if the user changed the amount of the item needed to repair. So I tried the InventoryEvent. I think I could basicly work with that, but the same problem as above occures. If I update the resulting item, the client doesn't update the item as normaly he doens't need to.
    Any ideas on other Events I could use, where the client also updates the resulting item in a working bench? Or do I really need to write a spout client plugin for this?
     
  2. Offline

    FrostyWolf



    Here's a short video showing this bug.
     
  3. Offline

    attrib

    Okay, maybe I'm on to something. I found the Packet103SetSlot, but I can't find any good documentation how to use it.

    Here is what I'm doing:
    Code:
    for (HumanEntity entity : event.getViewers()) {
        if (entity instanceof CraftPlayer) {
            CraftPlayer player = (CraftPlayer) entity;
            player.getHandle().netServerHandler.sendPacket(new Packet103SetSlot(1, 0, CraftItemStack.createNMSItemStack(repairedItemStack)));
        }
    }
    Tried 0, 1, 2 as window id (first parameter of Packet103SetSlot), but I think this should be 0 or 1. Als tried some slot ids (second parameter), but nothing works. But in general this sound like what I want. Theoreticly I think this should work. Added some logging for testing purposes, where the player is really me and the netServerHanlder is set. No errors occure, but also this didn't fix the issue.

    But I have no idea, why this doesn't work and how I should do this correctly. Any Ideas appreciated.
     
  4. Offline

    Njol

    Have you already tried calling player.updateInventory() after setting the item in the grid?
     
  5. Offline

    attrib

    Firstly this method is deprecated and secondly this makes it somehow worse. But thats what I'm looking for. Is there the same function for only a specific slot? If I take the repaired item out, it removes it from the cursor and the item disappear, but updates the amount of the item need to repair it. :p
    I will have a look into the source of bukkit, what it does when updateInventory is called. Maybe I can use this. Thanks for the hint.
     
  6. Offline

    attrib

    Yeah, I fixed it.

    Here the method i wrote for this.
    Code:
    public void updateSlotInventory(Player player, ItemStack item, int index) {
        if (player instanceof CraftPlayer && item instanceof CraftItemStack) {
            CraftPlayer craftPlayer = (CraftPlayer) player;
            CraftItemStack craftItemStack = (CraftItemStack) item;
            if (craftPlayer.getHandle().activeContainer != null) {
                Packet103SetSlot packet = new Packet103SetSlot();
                packet.a = craftPlayer.getHandle().activeContainer.windowId;
                packet.b = index;
                packet.c = craftItemStack.getHandle();
     
                craftPlayer.getHandle().netServerHandler.sendPacket(packet);
            }
        }
    }
     
Thread Status:
Not open for further replies.

Share This Page