Solved Get slot of dropped itemStack

Discussion in 'Spigot Plugin Development' started by CoolBoy, Jul 24, 2018.

Thread Status:
Not open for further replies.
  1. Hi people.

    In general, i have a task, before each change of the itemstack in the hand to do something depending on the itemstack. I decided to create my own event first:
    Code (Java):

    @Data
    @EqualsAndHashCode (callSuper = true)
    public abstract class EquipmentEvent
    extends PlayerEvent
    implements Cancellable
    {
        private ItemStack item;

        private boolean cancelled;

        public EquipmentEvent(Player player, ItemStack item)
        {
            super(player);

            this.item = item;
        }
    }
     
    Code (Java):

    @Data
    @EqualsAndHashCode (callSuper = true)
    public class PlayerUnequipItemEvent
    extends EquipmentEvent
    {
        private static final HandlerList HANDLER_LIST = new HandlerList();

        public PlayerUnequipItemEvent(Player player, ItemStack item)
        {
            super(player, item);
        }

        @Override
        public HandlerList getHandlers()
        {
            return HANDLER_LIST;
        }

        public static HandlerList getHandlerList()
        {
            return HANDLER_LIST;
        }
    }
     
    Problem:
    If a player throws itemstack - he, in fact, takes it off. Accordingly, I need to call PlayerUnequipItemEvent. The problem is that when I throw away itemstack I can only get ItemStack and player. However, I can not find out whether he was lying in the hands of the player before throwing out, or not. However, I must call an event only if the itemstack lay before it in main hand of player.

    Now I can track the drop of itemstack by pressing "Q" (and do all that I need). The problem now is to track the way to throw the itemStack. If the player throws it through an empty space on the right or left of the open inventory - I need to cancel event.

    Does anyone have any idea?
     
    #1 CoolBoy, Jul 24, 2018
    Last edited: Jul 24, 2018
  2. The only thing I can think of is to use a Runnable to store the player's item inside a Map<UUID, ItemStack>. Update the map every so often and then when a player drops an item check, if the player's UUID is inside the Map. If it is, compare the two ItemStacks.
     
  3. I did not find such a method. The version of your API?

    Now the problem arises only when I throw a itemstack out of the inventory by simply moving the stack to an empty space. I tried to track this through InventoryClickEvent, but when I click on an empty spot in the inventory, the event is not called.

    [Update]
    In general, it would be very handy if in the PlayerItemDropEvent added DropCause with the cause of the drop.

    For example:
    DropCause.KEY (when player press Q), DropCause.INVENTORY (when player drop itemstack from inventory)
     
    #3 CoolBoy, Jul 24, 2018
    Last edited: Jul 24, 2018
  4. Yeah, deleted the comment because I realized that the method doesn't exist. Thought I remembered a method like it, rip, but oh well.
     
  5. Can you explain what "if the itemstack lay before it in main hand of player" means?

    Edit: dunno if this is helpful but there is a PlayerDropItemEvent
     
  6. I apologize for my broken English.

    PlayerDropItemEvent will not help me with anything, since all I can get is an itemstack and a player.

    Once again: now I need to somehow check how the player throws out the itemstack. If the stack is thrown through the player's inventory (by clicking on the empty space on the right or on the left) - cancel the event.
     
  7. I am pretty sure when you click on the right or the left sides of the inventory, the InventoryClickEvent is called with a null inventory.
     
  8. Just use codingforcookies's armor equipment lib
     
  9. Yes you are right. At the moment I made a small crutch:
    Code (Java):

    if (event.getSlotType() == InventoryType.SlotType.OUTSIDE)
    {
       Vector vector = player.getLocation().add(0, 1, 0).getDirection().multiply(2);
     
       player.getWorld().dropItem(player.getEyeLocation().add(vector), cursorItem);
     
       event.setCursor(null);
       event.setCancelled(true);
       return;
    }
     
    In theory, if the player throws an itemstack from the inventory - I cancel the event (InventoryClickEvent), throw out the itemstack by myself bypassing the PlayerDropItemEvent. In practice, this leads to another minus - any itemstack thrown through the inventory will now be tracked through the PlayerDropItemEvent will not. However, i can make my event (ex. PlayerDropItemFromInventoryEvent) and call it here.

    Looks interesting, but, as I understand it, this library is designed to work with armor. I also work with the itemstack in the main hand.

    Ok, so, i can mark this thread [SOLVED] and close it, because I solved my problem.
    Thank you all for your advice.
     
    #9 CoolBoy, Jul 25, 2018
    Last edited: Jul 25, 2018
Thread Status:
Not open for further replies.