InventoryMoveItemEvent behaviour.

Discussion in 'Spigot Plugin Development' started by Shin1gamiX, Sep 15, 2019.

  1. I've had to deal with IMIE several times and have had some questions for this event ever since, each time I had to work with it, I did some searching and found some sketchy solutions.

    My questions are:
    • When does this event fire?
      • In other words, does this only fire when a hopper attempts to transfer an item?
      • Does it fire whenever the inventory that the hopper is to transfer the item is full?
    • Is the maximum amount of items that can be transfered 64? (or 16 depending on max size)
    • Do items that are to be transfered get chosen from left to right? (So first one from the left available)
    • How would I go about changing the destination inventory? Meaning, how can I actually change for example the item from being transfered to the chest (since I'm dealing with chests) and actually send it to a different, custom inventory?
    • How does Initiator differ from Source? (Inventories)
     
  2. https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/inventory/InventoryMoveItemEvent.html
     
  3. I'm aware of the javadocs, though most of my questions can't be answered by it, for example it doesn't mention whether only hoppers fire this event, they are only mentioned as an example.

    It also doesn't specify what an initiator is and how it differs from the source inventory.

    Javadocs also do not specify an exact behaviour since it says 'will try', try means it will attempt. Thus shows a chance of failing. Also says 'may already have', which indicates doubt?

    To make it clear, I'm aware of the javadocs, I'd appreciate it if you could share any knowledge you have on the specific event and perhaps answer my questions.
     
  4. @Shin1gamiX
    • Only a hopper? For sake of devil's advocate, maybe not the only case, but the only case I can think of at the moment. Main point is that there's an InventoryHolder of sorts initiating a transfer by its own volition. Whether it fires when the destinationInventory is full is up to you to debug.
    • Maximum amount of items to be moved in one fire would likely be the max stack size for ItemStack, 64 to my knowledge. Not sure if I've ever witnessed an initiator moving more than one item at a time, though.
    • It's likely the item is added to the slot that is returned by either: Inventory#first(ItemStack item) or Inventory#firstEmpty() elsewise. It's the behavior I'd expect of vanilla.
    • Changing the destination to a custom inventory would likely require cancelling the event, removing the item from the source yourself, and then adding the item to the inventory yourself. Ugly, but there doesn't seem to be any methodology within the API that supports this in the context of this event.
    • The initiator is a different object entirely. Source refers to, for instance, a chest that is being drawn from. The initiator in such a case would be the hopper's inventory, i.e. the source inventory is the chest, and the item is going to the hopper as a result of the hopper's initiation/attempt. The direction the items are flowing (into the hopper vs out of the hopper) is determined by what's passed into the constructor:
    Code (Java):
    InventoryMoveItemEvent(Inventory sourceInventory, ItemStack itemStack, Inventory destinationInventory, boolean didSourceInitiate)
    Edit: Also, @Sullivan_Bognar, kind of a boneheaded move to link the JavaDocs to someone with 2600 posts on the forum.
     
    • Like Like x 2
  5. You're right, that was my mistake lol.
     
    • Agree Agree x 1
    • Funny Funny x 1
  6. You can allways insert a debug line to inform you that the event was not involving a hopper.

    There are other possible situations where an inventory is moved to another inventory, hopefuly, most of these would be dealt with by a seperate event.
     
  7. I've been trying to figure out what other "entities" would be able to cause this but wasn't able to.
     
  8. Lets start of by clarifying all questions are clearly laid out in javadocs and/or hopper minecraft wiki. First one being the only slightly obscure one.
    • When does this event fire?
      - From experience it fires everytime an item gets moved from an inventory and is able to be, EG: if destination is full it doesnt fire. Hoppers, droppers/or dispensers(I forget which or both) and HopperMineCart are the only things that fire this event.
    • Is the maximum amount of items that can be transfered 64? (or 16 depending on max size.)
      - The maximum item moved is 1, hoppers can't move more than one item each tick... Of course you can change the itemstack to move 64 or things, but default behavior is 1.
    • Do items that are to be transfered get chosen from left to right? (So first one from the left available.)
      - First one left available, just like it does in game. Please remember Spigot is just an API that hooks from NMS/minecraft behavior.
    • How would I go about changing the destination inventory? Meaning, how can I actually change for example the item from being transfered to the chest (since I'm dealing with chests) and actually send it to a different, custom inventory?
      - Is there and setdestination event? Else, just cancel event, remove items from source, add items to your inventory. Should be something you can come up with yourself. :p There is some ambiguity here, but I have never seen the event fire before items are put into the destination inventory. Please note what the JavaDocs say about changing the itemstack though.
    • How does Initiator differ from Source? (Inventories.)
      - The source is where the item comes from, destination where it goes to and, drumroll pelase, initiator initiates the transfer! You even seen a chest move an item into another chest? Hoppers move items, chests don't.
    I am not trying to be mean, but it baffles me how little people sometimes know about the game, or fail to read alternative sources like the minecraft wiki, which honestly is an amazingly detailed source of info.
     
    • I've tried searching even further but was unable to find a list of blocks or entities that would fire the event. Actually took it on a bit of testing and realized that the event doesnt fire if the destination inventory is full. However, it instantly (or rapidly, fast, not instantly) fires the event once some space has been detected.
    • Just tested it and realized that no matter what I set the spigot.yml option of hopper transfer amoun to, it will not transfer more than the max size of the stack currently to be transfered.
    • I had to deal with this in the past, there was no other solution that I and some other users in the forums were aware of other than cancelling the event and scheduling a delayed task on a single tick to remove the item appropriately from the source inventory and then adding it to the destination.
      • An issue with this? Results in regards to what item would be selected or what would happen after that one tick are unknown. It's always scarry to not have things being run in order, so issues like item loss may be a thing (not that they may be noticeable but still)
    • So from what I understood, the source and the initiator in the case of a hopper are the same inventories?

    • From experience isn't much. From my experience, I've only encountered hoppers so far (haven't tested minecart hoppers but I assume they should have the same behaviour).
      • How come dispensers or droppers fire the event? What inventory would be the destination in the case of them firing it?
    • When saying item are you referring to the whole stack or the amount of a stack? I'm aware that the default behaviour is 1 and that it can be changed in the spigot.yml file to anything else, but I was wondering whether the amount could be changed to more than the max stack size (128 for example, which is 2 stacks). I tested this a bit and realized that no matter what you set it, the max size will always be the limit.
    • I don't generally play minecraft, thus me making this question, I'm not fully aware of the hopper's functionality and how it operates. I'm planning on manipulating hoppers so this is one of the main reasons I'm dealing with them right now.
    • There is no setDestination event, that'd be quite convenient and I wouldn't be here if there was. If it was as simple as cancelling the event, removing and adding items from inventories, I would be extremely happy and wouldn't be here for that matter as well.
      • When cancelling the event, according to javadocs, which I am fully aware of once again, mention that once the event has been cancelled, the item (if unchanged, not sure what'll happen if changed), will go back to the source inventory. In that case, I'd be force to schedule a delayed task in order to allow the item to go back into the source inventory. Indeed this is something I can come up with, myself, but I'm looking whether there is an alternative to this.
    • If the initiator is the hopper, and the hopper is also the source, how do these two inventories differ? In what case would the initiator be something different to the source? Won't try to sound mean but your answer to this was sort of foolish, from my perspective.
    I obviously appreciate both of your times into writing these replies.
    @Kilian544, instead of being baffled from my minecraft wiki knowledge or failling to search for alternative soruces, would you actually mind sharing the links to where you found information from, in regards to this matter?

    I seem unable to find ANY information or list to which mentions what entities or blocks fire the event.
     
    • From experience isn't much. From my experience, I've only encountered hoppers so far (haven't tested minecart hoppers but I assume they should have the same behaviour).
      - Well, I've used it for quite a bit and never ran into any problems so I guess my experience and assumptions were correct.
      • How come dispensers or droppers fire the event? What inventory would be the destination in the case of them firing it?
        - A dropper and (maybe) a dispenser can put items into another dropper/hopper/(possible) dispenser, chests I am not sure about. An dispenser can also put armour in a players armour slot, which I believe fires this event, you'd have to check as I am not entirely sure though. Dropper wiki, check redstone component - behavior section. Dispenser, again, redstone component section.
    • When saying item are you referring to the whole stack or the amount of a stack? I'm aware that the default behaviour is 1 and that it can be changed in the spigot.yml file to anything else, but I was wondering whether the amount could be changed to more than the max stack size (128 for example, which is 2 stacks). I tested this a bit and realized that no matter what you set it, the max size will always be the limit.
      - I use item kinda interchangably, read ItemStack/Material/new ItemStack(material, 1) though, amount would be just size. Generally max stack is exactly that, max stack size. In the past exploits used to work with bigger stacks but they have been gone for a long while. I believe minecraft itself checks if the stack is more than 64, read 64 and not max-stacksize of an item (not 1 or 16 always 64), it will set the amount back to 64. Thus you can still make swords or eggs stack to 64, but never anything higher than 64.
    • I don't generally play minecraft, thus me making this question, I'm not fully aware of the hopper's functionality and how it operates. I'm planning on manipulating hoppers so this is one of the main reasons I'm dealing with them right now.
      - Check out the wiki for hoppers, everything is there.
    • There is no setDestination event, that'd be quite convenient and I wouldn't be here if there was. If it was as simple as cancelling the event, removing and adding items from inventories, I would be extremely happy and wouldn't be here for that matter as well.
      • When cancelling the event, according to javadocs, which I am fully aware of once again, mention that once the event has been cancelled, the item (if unchanged, not sure what'll happen if changed), will go back to the source inventory. In that case, I'd be force to schedule a delayed task in order to allow the item to go back into the source inventory. Indeed this is something I can come up with, myself, but I'm looking whether there is an alternative to this.
        - The JavaDocs says:
        "- If this event is cancelled, the items will be returned to the source inventory, if needed.
        - If this event is not cancelled, the initiator will try to put the ItemStack into the destination inventory. If this is not possible and the ItemStack has not been modified, the source inventory slot will be restored to its former state. Otherwise any additional items will be discarded."
        Unchanged or not items aren't discussed when the event gets canceled, thus the item would just be moved back. If the item is changed, the original item will be restored I believe. There is some real poor wording here, I take a clue from additional items being discarded, meaning "SOME" item, presumably the original, will be put back. I also doubt if you'd change the size to less than original the lesser itemstack would be put back instead of the original, since why would someone only put back less items if they change the size, and only the original if size is more. (I realize I kinda went on a rant here, I'll try and think about a better way of explaining, ask any further questions ou have about this if you want.)
    • If the initiator is the hopper, and the hopper is also the source, how do these two inventories differ? In what case would the initiator be something different to the source? Won't try to sound mean but your answer to this was sort of foolish, from my perspective.
      - If the source is initiator they wouldn't, if the hopper is below a chest, the source would be an chest and the destination, the hopper, is the initiator. It gets funky with hopper to hopper transfer but I believe the initiator would always be the bottom. Else items would instantly be transported down if they point into each-other downwards.
    Links:
    Minecraft wiki hopper, specifically check out the redstone component section. Here you can also find any block ever interacting with another, thus any related to the event here.