[API 6.0.0]Find the inventory associated with a SlotTransaction

Hello,

I’m trying to develop a plugin to log ItemStacks tranfers between a player’s inventory and chest’s inventory.
I think ChangeInventoryEvent.Transfer would do what I want but it isn’t documented and from GitHub seems to be not implemented either.

Therefore, I’m currently listening to ClickInventoryEvent events to find what ItemStacks are being transferred. I can get the ItemStacks transferred but I’m unable to know wether the ItemStacks are going to the chest’s inventory or the player’s one.

Indeed with SpongeForge 1.10.2 build 2321 (I think it also works with later build of SpongeForge 1.10.2 even if I didn’t tested it out) I could get the target of the transfer with something like this:

ClickInventoryEvent event = ...;
Inventory parent = event.getTransactions().get(0).getSlot().parent();

When the ItemStack was being transferred to the chest, parent was an instance of Chest and when it was being transferred to the player’s inventory, parent was an instance of PlayerInventory. This way, I was able to know in which direction the transfer was going.

But as of SpongeForge 1.11.2 build 2352,

event.getTransactions().get(0).getSlot().parent() == event.getTargetInventory()

is always true and event.getTargetInventory() is always an instance of ContainerChest. Therefore I’m unable to tell in which direction the transfer is going.

How can I know if the ItemStack is being transferred to the chest or the player’s inventory ?
Does the API changed ? Is it a bug or is it still unimplemented in SpongeForge 1.11.2 ?

Thanks

Well damnit.
The Slot-parent is always the container so you don’t have multiple slots with the same SlotIndex and so with that fix
now you cannot directly check what inventory the clicked slot is in.

You could use this to detect if a slot is in the “first” inventory:

int upperSize = event.getTargetInventory().iterator().next().capacity();
for (SlotTransaction transaction : event.getTransactions())
{
    Integer affectedSlot = transaction.getSlot().getProperty(SlotIndex.class, "slotindex").map(SlotIndex::getValue).orElse(-1);
    boolean upperInventory = affectedSlot != -1 && affectedSlot < upperSize;    
    // do stuff
}
1 Like

Alright, I understand that the previous behavior was a mistake and why now the parent is always the container.

Now, according to your code, it seems the child inventories of the Container are returned from the iterator in the same order as they appear from top to bottom on screen. Am I right ?

I listed and displayed each children of the container:

for (Inventory child : event.getTargetInventory()) {
    logger.debug(child.toString());
}

I noticed that everytime, the last two inventories are the GridInventory and the Hotbar of the player. Is this something intended ? Will it stay the same forever (at least for API 6) ? Can I rely on this fact to detect where the transferred ItemStack is going ?

The order is the same as it is in the Minecraft-Implementation.
So for vanilla currently its always viewed inventory followed by playerinventory with hotbar.
But mods can do what they want.

I was thinking about wrapping the “main” player inventory and hotbar so the Container only has 2 sub-inventories.
So that will maybe change but not in API6

Thank you very much.
I will use this assumption and if one day I discover a mod which breaks, I will detect and handle things differently when the transfer is being done with this mod’s related inventories.

Solved ! :slight_smile: