How to remove items via ClickInventoryEvent


#1

Ok, so I’m working on a “shop” plugin for vanillasponge and I’m trying to remove the item from the shop inventory upon purchase.
so my current code is something along the lines of

@Listener
public void onInventoryClicked(ClickInventoryEvent e) {
	Optional<Player> optPlayer = e.getCause().first(Player.class);
	ItemStack tmp = e.getCursorTransaction().getDefault().createStack();
	optPlayer.get().getInventory().offer(tmp);
    optPlayer.get().sendMessage(Text.of("Items successfully purchased!"));
}

So the item gets purchased, but I have no idea how to remove it from the shop inventory, which is just a double chest inventory.

So far I’ve tried

npc.storage.query(QueryOperationTypes.ITEM_STACK_EXACT.of(tmp)).poll();

and

Optional<ItemStack> is = npc.storage.query(QueryOperationTypes.ITEM_STACK_EXACT.of(tmp)).poll();
is.ifPresent(itemStack -> itemStack.setQuantity(0));

and

for(int i = 0; i < npc.storage.capacity(); i++) {
    Optional<ItemStack> is = npc.storage.query(QueryOperationTypes.INVENTORY_PROPERTY.of(SlotIndex.of(i))).peek();
    if(is.isPresent() && is.get().equals(tmp)){
        is.get().setQuantity(0);
        break;
    }
}

but none of the above seems to do anything.

Also, even if I cancel the event before running the last piece of code, the inventory is missing the clicked itemstack.

The inventory is stored in the ArrayList, so something could be up with the mutability. I just don’t know how this complicated spongeapi works.

I’m a long-term Bukkit/Spigot dev, so I know (at least partially ;)) how to code, but this is my first plugin in Sponge, so please don’t hate.

Kind regards, MGlolenstine


#2

The sponge inventory api was designed in mind of hooking with Forge mods that can have … Complex inventory systems that never touch any of the original minecraft inventory code. So its a bit more complex then your bukkit api inventory.

However thankfully you chose a easy event to use. I would do something like this

Optional<Slot> opSlot = event.getSlot();
if(!opSlot.isPresent()){
    event.setCancelled(true);
    return; //not sure how it can return optional but sponge think it can
}
Slot slot = opSlot.get();
ItemStack stack = slot.peek(); //gets the exact item in that slot for giving to the player
slot.set(ItemStackSnapshot.NONE.createStack()); //clears the slot

The code provided was from memory so sorry if i get syntax wrong.


#3

I’ll try it out and accept the answer, thanks for your help!


#4

It is Optional because there are events where there is no primary clicked Slot. e.g. drag events


#5

Ok, testing it out reveals, that there’s no such thing as ClickInventoryEvent#getSlot(). It’s probably a syntax error, so could you please fix it, as I have no idea where to get that slot from otherwise?

Kind regards, MGlolenstine


#6

It’s a rather “new” addition (on 3 Dec 2018)


#7

Interesting… Obviously I’m running an obsolete version then. Thanks! I’m running 7.0.0.


#8

Yep, that’s the issue. That method was added after our last API recommended version (but is still available in recommended versions for SpongeForge and SpongeVanilla). If you’re using Maven or Gradle for your dependencies (recommended), you’ll want to use 7.2.0-SNAPSHOT. If not, download the latest SpongeAPI JAR file.