Hi,
The title says all. I’m trying to just cancel the block change and not the ItemStack change. I tried to invalidate block transations but it also cancel the holded item modification. If anyone know or think about a workaround, post it here
Its been a long time since i have needed to cancel that event with the itemstack in tacked. The problem is that event is fired after the itemstack is modified (it maybe in the cause - really can not remember).
But if i remember, I fixed the issue by “cancelling” a event before hand. I believe it was InteractBlockEvent.Secondary and checked that the item in the hand was a block. I believe sponge have added some methods to that event for checking if its a block as the item.
I can do some testing but it may take a while as im pretty busy.
What you could do is capture the snapshot before hand, then create a scheduled task for a few ticks later to reduce the itemstack total by 1 (With appropriate filters to check that the item stack was indeed canceled)
Yes, I thook about that but it seems to be a bit tricky. Is it really the best solution ?
Sorry I misread the “without”, it used to be that the event fired and if you cancelled it the itemstack would have still been modified. Anyway here is how I would do it (btw its tested)
@Listener
public void onBlockPlace(ChangeBlockEvent.Place event, @Root Player player){
Optional<ItemStackSnapshot> opItem = event.getCause().getContext().get(EventContextKeys.USED_ITEM);
if(opItem.isPresent()){
if(player.get(Keys.GAME_MODE).get().equals(GameModes.CREATIVE)){
return;
}
ItemStackSnapshot snapshot = null;
if(opItem.get().getQuantity() == 1){
snapshot = ItemStackSnapshot.NONE;
}else{
snapshot = ItemStack.builder().fromSnapshot(opItem.get()).quantity(opItem.get().getQuantity() - 1).build().createSnapshot();
}
for (Inventory sInv : player.getInventory().slots()){
if(!sInv.peek().isPresent()){
continue;
}
int compare = ItemStackComparators.ALL.compare(sInv.peek().get(), opItem.get().createStack());
if(compare != 0){
continue;
}
final ItemStackSnapshot snapshot1 = snapshot;
Sponge.getScheduler().createTaskBuilder().execute(() -> sInv.set(snapshot1.createStack())).delayTicks(1).submit(Main.this);
break;
}
event.setCancelled(true);
}
}