Open / Edit Chest Discreetly

Discussion in 'Plugin Development' started by Maurdekye, Mar 21, 2014.

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

    Maurdekye

    I'm trying to make a plugin that allows you to open a chest from a distance without it showing the open animation. Unfortunately, showing the player the inventory that the chest contains, as in the code below, still shows the opening animation;
    Code:java
    1. Block targetBlock = /*chest player is looking at*/;
    2. Chest chest = (Chest) targetBlock.getState();
    3. ply.openInventory(chest.getInventory());
    4.  

    I got around it by creating an entirely new inventory with all the contents of the chest, with the code below;
    Code:java
    1. Chest chest = (Chest) target.getState();
    2. Inventory cInv = chest.getInventory();
    3. Inventory copy = Bukkit.createInventory(chest, cInv.getType());
    4. for (int i=0;i<cInv.getContents().length;i++)
    5. copy.setItem(i, cInv.getContents()[i]);
    6. ply.openInventory(copy);[/i]

    But the inventory was no longer linked to the chest, so I had no way of changing around the items in it with the displayed inventory. I suppose I could put the information for the chest's position in it's name, but that would be visible and ugly, and there's a limit on how much information can be stored there.
    Is there a way I can store arbitrary invisible information within an Inventory object, so that I can use it to determine the parent chest it represents?


    Well, i've come up with a separate solution that completely negates this problem, but it's still nagging. I'll leave it unsolved for now as a result.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 7, 2016
  2. Offline

    willeb96

    Try player.openInventory(chest.getInventory());
     
  3. Offline

    desht

    You've already got the information you need; when you created your virtual copy Inventory, you passed it a reference to the Chest object. You can get chest that back at any time with copy.getHolder(). http://jd.bukkit.org/dev/apidocs/org/bukkit/inventory/Inventory.html#getHolder()

    So hook the InventoryCloseEvent and check the inventory's holder; if it's one of your "stealth chests", copy your virtual inventory back to the original chest. (You should also validate that the holder is still valid in case someone breaks the chest in the meantime; at least make sure the Chest object still has a chest block at its Location).

    Another problem with all this is that someone else may have interacted with the chest while your virtual inventory was open, and their changes to the chest's real inventory could end up being lost. Merging the inventories cleanly is highly non-trivial (simplest option may be to just prevent other players interacting with the chest while a player has the virtual inventory open).
     
  4. Offline

    nlthijs48

  5. Offline

    Maurdekye

    desht Ah, thank you. That's much better that what I came up with. (Basically I was storing a hashmap of chests, which contained the chest that each player last opened. Which probably wasn't good for memory.)

    Unfortunately, I have to unmark this thread as solved as I've come to another standstill. I'm able to have the player edit a chest from a distance, but they can't see changes done to the chest from someone accessing it directly at the time. I'm not sure how to go about this other than constantly updating the viewer's inventory every single tick, which for obvious reasons is not the best solution.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 7, 2016
  6. Offline

    willeb96

    The issue might be that the chest is in an unloaded chunk.
     
Thread Status:
Not open for further replies.

Share This Page