Solved Per User Chest Inventory

Discussion in 'Plugin Development' started by stoi2m1, Jan 10, 2017.

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


    I have a mostly working plugin to handle this.

    However my problem is as follows when two players are accessing the same chest:
    Player A opens a chest and get loots (loot is randomly loaded on a timed basis from a loot table in a config file).
    Player B opens chest and gets different loot (same method to load loot).
    Player A now sees Player B's loot (this is where my problem is).

    How can I separate the viewed inventories so they do not overwrite each other. Iv'e read some posts discussing canceling the event and displaying a new inventory GUI. None of the code I saw for this was meaningful or worthwhile. How can this be done and still have the animation and sound of the chest opening?

    I could share some code, but I figured since this post is more about whats not in my code than what is in my code it wouldn't really help the discussion.
  2. Just create a new Inventory instance for every GUI the player opens. It seems like you only have 1 instance, which you use for both players, this will result in them seeing the same Inventory.
    kameronn likes this.
  3. Offline


    As what DoggyCode said put the inventory object inside the method you're opening it
  4. Offline


    ok I understand now. I was using the event inventory to load the item stack into the view of both players.

    I generated a new inventory by using the following, this way the GUI is the same size as the inventory opened.
    Inventory inv = Bukkit.createInventory(null, inventory.getSize(), "Chest");

    I tired using the below to close the event inventory and load the new GUI inventory but it didnt do anything

    I used the following to view the new GUI, but I lost the audio for chest opening and the animation

    How can I restore the audio and the animation? I saw some where the use of packets to fix this situation but I do not understand how to implement that.
  5. Offline


    player.playSound(player.getLocation(), Sound.CHEST_OPEN, 1, 1);
    public void onInventoryClose(InventoryCloseEvent e) {
    Player p = e.getPlayer();
    Inventory inv = e.getInventory();
    if(inv.getName().equalsIgnorecase("Name HEre")) {
    player.playSound(player.getLocation(), Sound.CHEST_CLOSE, 1, 1);
  6. Offline


    OK, I get the sound working but only the person opening the chest can hear the sound. I was hoping for some sort of radius around the chest would others hear it too.

    I changed the code to look like this hoping for a 10 block radius and that didn't seem to work. How is that done?
    player.playSound(player.getLocation(), Sound.CHEST_OPEN, 10, 1);

    Also I seem to be having some sort of error in the InventoryOpenEvent. It seems if both people click on the same chest at the same time the event isnt canceled rather it successfully complete and the Chest GUI is displayed rather then my new instance of a Custom GUI. Also all sequential clicks on any chest end up displaying the Chest GUI and not my Custom GUI.

    Here is a paste bin with the code in the event handler
  7. Then use World#playSound
  8. Offline


    Thank you, Ive updated my code, but am not able to test yet.

    However I am still have the chest GUI issue mentioned in the post above and I believe the issue only occurs when both players click the same chest in the same tick.

    I am tracking chest inventory by location in a PlayerInteractEvent is there a way to get the location from the InventoryOpenEvent so that I may eliminate the need for the extra event. This would be helpful to simplify my code but probably not going to help fix my issue. Although the worthiness of opening new loot vs old loot is built upon the condition of time and location within the interact event. If you see this as part of my potential conflict please direct me in a better direction for handling the location of the chest within the InventoryOpenEvent.
  9. Offline


    So I have verified the sound works like i want where everyone in near the event can hear it thanks.

    I have been trying to reduce the amount of events I am dealing with and have found how to get the location based on the inventory open event by casting the inventory holder to a chest and getting the chests location like so

    public void onChestOpen(InventoryOpenEvent event) {
            Player player = (Player) event.getPlayer();
            Inventory inventory = event.getInventory();
            InventoryType invtype = inventory.getType();
            if( invtype != InventoryType.CHEST )
            Chest chest = (Chest) inventory.getHolder();
            Location chestLocation = chest.getLocation();
            System.out.println("Chest Location "+chestLocation);

    However the line Location chestLocation = chest.getLocation(); kicks out a null pointer error, but the system out prints a good location.

    Any idea why this is happening. Is there something I am doing wrong or should I just suppress the issue.
    Last edited by a moderator: Jan 14, 2017
  10. Offline


  11. Offline


  12. Offline


    I actually found my problem.

    I was opening a new instance of an inventory, that was firing my event method and this was returning null on the chest location since it isnt actually a chest.

    I added a line to verify and return out of the method if its the new instance.
Thread Status:
Not open for further replies.

Share This Page