Search in sources :

Example 1 with ClickContainerEvent

use of org.spongepowered.api.event.item.inventory.container.ClickContainerEvent in project SpongeCommon by SpongePowered.

the class ClickMenuTransaction method createInventoryEvent.

@Override
Optional<ClickContainerEvent> createInventoryEvent(final List<SlotTransaction> slotTransactions, final List<Entity> entities, final PhaseContext<@NonNull ?> context, final Cause cause) {
    final ItemStackSnapshot resultingCursor = ItemStackUtil.snapshotOf(this.player.inventory.getCarried());
    final Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(this.cursor, resultingCursor);
    @Nullable final ClickContainerEvent event = context.createContainerEvent(cause, this.player, (Container) this.menu, cursorTransaction, slotTransactions, entities, this.buttonNum, this.slot);
    return Optional.ofNullable(event);
}
Also used : SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) Transaction(org.spongepowered.api.data.Transaction) ClickContainerEvent(org.spongepowered.api.event.item.inventory.container.ClickContainerEvent) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 2 with ClickContainerEvent

use of org.spongepowered.api.event.item.inventory.container.ClickContainerEvent in project SpongeCommon by SpongePowered.

the class ContainerBasedTransaction method generateEvent.

@Override
public Optional<ClickContainerEvent> generateEvent(final PhaseContext<@NonNull ?> context, @Nullable final GameTransaction<@NonNull ?> parent, final ImmutableList<GameTransaction<ClickContainerEvent>> gameTransactions, final Cause currentCause) {
    final ImmutableList<ContainerBasedTransaction> containerBasedTransactions = gameTransactions.stream().filter(tx -> tx instanceof ContainerBasedTransaction).map(tx -> (ContainerBasedTransaction) tx).filter(tx -> !tx.used).collect(ImmutableList.toImmutableList());
    if (containerBasedTransactions.stream().map(c -> c.isContainerEventAllowed(context)).filter(b -> !b).findAny().orElse(false)) {
        SpongeCommon.logger().warn("No event will be fired for existing ContainerBasedTransactions: {}", containerBasedTransactions.size());
        return Optional.empty();
    }
    if (!((TrackedContainerBridge) this.menu).bridge$capturePossible()) {
    // if (ContainerBasedTransaction.containersFailedCapture.add(this.menu.getClass())) {
    // SpongeCommon.logger()
    // .warn("Changes in modded Container were not captured. Inventory events will not fire for this. Container: " + this.menu.getClass());
    // }
    }
    final List<Entity> entities = containerBasedTransactions.stream().map(ContainerBasedTransaction::getEntitiesSpawned).flatMap(List::stream).collect(Collectors.toList());
    final List<SlotTransaction> slotTransactions = containerBasedTransactions.stream().map(ContainerBasedTransaction::getSlotTransactions).flatMap(List::stream).collect(Collectors.toList());
    if (this.craftingInventory != null) {
        // Event with Preview transaction on crafting inventory?
        Slot slot = this.craftingInventory.result();
        @Nullable final SlotTransaction preview = this.findPreviewTransaction(this.craftingInventory.result(), slotTransactions);
        final ItemStackSnapshot previewItem = ItemStackUtil.snapshotOf(this.craftingInventory.peek());
        if (preview != null) {
            slot = preview.slot();
            // Check if preview transaction is correct
            if (!preview.defaultReplacement().equals(previewItem)) {
                slotTransactions.remove(preview);
                slotTransactions.add(new SlotTransaction(slot, preview.original(), previewItem));
            }
        } else if (!previewItem.isEmpty()) {
            slotTransactions.add(new SlotTransaction(slot, previewItem, previewItem));
        }
    }
    for (final ContainerBasedTransaction transaction : containerBasedTransactions) {
        transaction.used = true;
    }
    final Optional<ClickContainerEvent> event = containerBasedTransactions.stream().map(t -> t.createInventoryEvent(slotTransactions, entities, context, currentCause)).filter(Optional::isPresent).map(Optional::get).findFirst();
    if (!event.isPresent() && !slotTransactions.isEmpty()) {
        SpongeCommon.logger().warn("Logged slot transactions without event! {} {}", gameTransactions.size(), this.menu.getClass().getName(), new Exception(""));
        for (final SlotTransaction slotTransaction : slotTransactions) {
            SpongeCommon.logger().warn(slotTransaction);
        }
    }
    return event;
}
Also used : NonNull(org.checkerframework.checker.nullness.qual.NonNull) ClientboundContainerSetSlotPacket(net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket) AbstractContainerMenu(net.minecraft.world.inventory.AbstractContainerMenu) SpawnEntityTransaction(org.spongepowered.common.event.tracking.context.transaction.world.SpawnEntityTransaction) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) PrettyPrinter(org.spongepowered.common.util.PrettyPrinter) ClickContainerEvent(org.spongepowered.api.event.item.inventory.container.ClickContainerEvent) TransactionTypes(org.spongepowered.common.event.tracking.context.transaction.type.TransactionTypes) ArrayList(java.util.ArrayList) MonotonicNonNull(org.checkerframework.checker.nullness.qual.MonotonicNonNull) ServerPlayer(net.minecraft.server.level.ServerPlayer) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) TrackedContainerBridge(org.spongepowered.common.bridge.world.inventory.container.TrackedContainerBridge) ImmutableList(com.google.common.collect.ImmutableList) ItemStackUtil(org.spongepowered.common.item.util.ItemStackUtil) CraftItemEvent(org.spongepowered.api.event.item.inventory.CraftItemEvent) BiConsumer(java.util.function.BiConsumer) CauseStackManager(org.spongepowered.api.event.CauseStackManager) LinkedList(java.util.LinkedList) RecipeType(net.minecraft.world.item.crafting.RecipeType) Nullable(org.checkerframework.checker.nullness.qual.Nullable) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Set(java.util.Set) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) ContainerUtil(org.spongepowered.common.inventory.util.ContainerUtil) Slot(org.spongepowered.api.item.inventory.Slot) SpongeCommon(org.spongepowered.common.SpongeCommon) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) CraftingOutput(org.spongepowered.api.item.inventory.crafting.CraftingOutput) Entity(org.spongepowered.api.entity.Entity) Collectors(java.util.stream.Collectors) Player(net.minecraft.world.entity.player.Player) Cause(org.spongepowered.api.event.Cause) EntityUtil(org.spongepowered.common.entity.EntityUtil) List(java.util.List) CraftingContainer(net.minecraft.world.inventory.CraftingContainer) GameTransaction(org.spongepowered.common.event.tracking.context.transaction.GameTransaction) Container(org.spongepowered.api.item.inventory.Container) ReferenceOpenHashSet(it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet) PhaseContext(org.spongepowered.common.event.tracking.PhaseContext) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) CraftingRecipe(org.spongepowered.api.item.recipe.crafting.CraftingRecipe) PacketPhaseUtil(org.spongepowered.common.event.tracking.phase.packet.PacketPhaseUtil) Optional(java.util.Optional) ItemStack(net.minecraft.world.item.ItemStack) Collections(java.util.Collections) Entity(org.spongepowered.api.entity.Entity) Optional(java.util.Optional) ClickContainerEvent(org.spongepowered.api.event.item.inventory.container.ClickContainerEvent) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) Slot(org.spongepowered.api.item.inventory.Slot) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 3 with ClickContainerEvent

use of org.spongepowered.api.event.item.inventory.container.ClickContainerEvent in project SpongeCommon by SpongePowered.

the class PlaceRecipeTransaction method createInventoryEvent.

@Override
Optional<ClickContainerEvent> createInventoryEvent(final List<SlotTransaction> slotTransactions, final List<Entity> entities, final PhaseContext<@NonNull ?> context, final Cause cause) {
    final SlotTransaction preview = this.getPreviewTransaction(this.craftingInventory.result(), slotTransactions);
    final Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(this.originalCursor, ItemStackUtil.snapshotOf(this.player.inventory.getCarried()));
    ClickContainerEvent.Recipe event;
    if (this.shift) {
        event = SpongeEventFactory.createClickContainerEventRecipeAll(cause, (Container) this.menu, this.craftingInventory, cursorTransaction, preview, Optional.of((CraftingRecipe) this.recipe), Optional.empty(), slotTransactions);
    } else {
        event = SpongeEventFactory.createClickContainerEventRecipeSingle(cause, (Container) this.menu, this.craftingInventory, cursorTransaction, preview, Optional.of((CraftingRecipe) this.recipe), Optional.empty(), slotTransactions);
    }
    return Optional.of(event);
}
Also used : Container(org.spongepowered.api.item.inventory.Container) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) Transaction(org.spongepowered.api.data.Transaction) ClickContainerEvent(org.spongepowered.api.event.item.inventory.container.ClickContainerEvent) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction)

Example 4 with ClickContainerEvent

use of org.spongepowered.api.event.item.inventory.container.ClickContainerEvent in project SpongeCommon by SpongePowered.

the class SelectTradeTransaction method createInventoryEvent.

@Override
Optional<ClickContainerEvent> createInventoryEvent(final List<SlotTransaction> slotTransactions, final List<Entity> entities, final PhaseContext<@NonNull ?> context, final Cause cause) {
    final ItemStackSnapshot cursorItem = ItemStackUtil.snapshotOf(this.player.inventory.getCarried());
    final Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(cursorItem, cursorItem);
    if (this.menu instanceof MerchantMenu) {
        final MerchantOffer offer = ((MerchantMenu) this.menu).getOffers().get(this.tradeItem);
        final ClickContainerEvent.SelectTrade event = SpongeEventFactory.createClickContainerEventSelectTrade(cause, (Container) this.menu, cursorTransaction, Optional.empty(), (TradeOffer) offer, slotTransactions, this.tradeItem);
        return Optional.of(event);
    }
    SpongeCommon.logger().warn("SelectTradeTransaction without MerchantMenu");
    return Optional.empty();
}
Also used : MerchantMenu(net.minecraft.world.inventory.MerchantMenu) MerchantOffer(net.minecraft.world.item.trading.MerchantOffer) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) Transaction(org.spongepowered.api.data.Transaction) ClickContainerEvent(org.spongepowered.api.event.item.inventory.container.ClickContainerEvent) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot)

Example 5 with ClickContainerEvent

use of org.spongepowered.api.event.item.inventory.container.ClickContainerEvent in project SpongeCommon by SpongePowered.

the class ContainerBasedTransaction method markCancelledTransactions.

@Override
public boolean markCancelledTransactions(final ClickContainerEvent event, final ImmutableList<? extends GameTransaction<ClickContainerEvent>> gameTransactions) {
    if (event.isCancelled()) {
        event.transactions().forEach(SlotTransaction::invalidate);
        event.cursorTransaction().invalidate();
        if (event instanceof CraftItemEvent.Preview) {
            ((CraftItemEvent.Preview) event).preview().invalidate();
        }
        return true;
    }
    boolean cancelledAny = false;
    for (final SlotTransaction transaction : event.transactions()) {
        if (!transaction.isValid()) {
            cancelledAny = true;
            for (final GameTransaction<ClickContainerEvent> gameTransaction : gameTransactions) {
                ((ContainerBasedTransaction) gameTransaction).getSlotTransactions().forEach(tx -> {
                    if (tx == transaction) {
                        gameTransaction.markCancelled();
                    }
                });
            }
        }
    }
    return cancelledAny;
}
Also used : ClickContainerEvent(org.spongepowered.api.event.item.inventory.container.ClickContainerEvent) CraftItemEvent(org.spongepowered.api.event.item.inventory.CraftItemEvent) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction)

Aggregations

ClickContainerEvent (org.spongepowered.api.event.item.inventory.container.ClickContainerEvent)5 SlotTransaction (org.spongepowered.api.item.inventory.transaction.SlotTransaction)5 ItemStackSnapshot (org.spongepowered.api.item.inventory.ItemStackSnapshot)4 Transaction (org.spongepowered.api.data.Transaction)3 Nullable (org.checkerframework.checker.nullness.qual.Nullable)2 CraftItemEvent (org.spongepowered.api.event.item.inventory.CraftItemEvent)2 Container (org.spongepowered.api.item.inventory.Container)2 ImmutableList (com.google.common.collect.ImmutableList)1 ReferenceOpenHashSet (it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Optional (java.util.Optional)1 Set (java.util.Set)1 BiConsumer (java.util.function.BiConsumer)1 Collectors (java.util.stream.Collectors)1 ClientboundContainerSetSlotPacket (net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket)1 ServerPlayer (net.minecraft.server.level.ServerPlayer)1 Player (net.minecraft.world.entity.player.Player)1