Search in sources :

Example 1 with ChangeInventoryEvent

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

the class CommandState method unwind.

@Override
public void unwind(CommandPhaseContext phaseContext) {
    Optional<EntityPlayer> playerSource = phaseContext.getSource(EntityPlayer.class);
    if (playerSource.isPresent()) {
        // Post event for inventory changes
        ((IMixinInventoryPlayer) playerSource.get().inventory).setCapture(false);
        List<SlotTransaction> list = ((IMixinInventoryPlayer) playerSource.get().inventory).getCapturedTransactions();
        if (!list.isEmpty()) {
            ChangeInventoryEvent event = SpongeEventFactory.createChangeInventoryEvent(Sponge.getCauseStackManager().getCurrentCause(), ((Inventory) playerSource.get().inventory), list);
            SpongeImpl.postEvent(event);
            PacketPhaseUtil.handleSlotRestore(playerSource.get(), null, list, event.isCancelled());
            list.clear();
        }
    }
    final CommandSource sender = phaseContext.getSource(CommandSource.class).orElseThrow(TrackingUtil.throwWithContext("Expected to be capturing a Command Sender, but none found!", phaseContext));
    phaseContext.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(list -> TrackingUtil.processBlockCaptures(list, this, phaseContext));
    try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(sender);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PLACEMENT);
        phaseContext.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
            // TODO the entity spawn causes are not likely valid,
            // need to investigate further.
            final SpawnEntityEvent spawnEntityEvent = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), entities);
            SpongeImpl.postEvent(spawnEntityEvent);
            if (!spawnEntityEvent.isCancelled()) {
                final boolean isPlayer = sender instanceof Player;
                final Player player = isPlayer ? (Player) sender : null;
                for (Entity entity : spawnEntityEvent.getEntities()) {
                    if (isPlayer) {
                        EntityUtil.toMixin(entity).setCreator(player.getUniqueId());
                    }
                    EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                }
            }
        });
    }
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(sender);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
        phaseContext.getCapturedEntityDropSupplier().acceptIfNotEmpty(uuidItemStackMultimap -> {
            for (Map.Entry<UUID, Collection<ItemDropData>> entry : uuidItemStackMultimap.asMap().entrySet()) {
                final UUID key = entry.getKey();
                @Nullable net.minecraft.entity.Entity foundEntity = null;
                for (WorldServer worldServer : WorldManager.getWorlds()) {
                    final net.minecraft.entity.Entity entityFromUuid = worldServer.getEntityFromUuid(key);
                    if (entityFromUuid != null) {
                        foundEntity = entityFromUuid;
                        break;
                    }
                }
                final Optional<Entity> affectedEntity = Optional.ofNullable((Entity) foundEntity);
                if (!affectedEntity.isPresent()) {
                    continue;
                }
                final Collection<ItemDropData> itemStacks = entry.getValue();
                if (itemStacks.isEmpty()) {
                    return;
                }
                final List<ItemDropData> items = new ArrayList<>();
                items.addAll(itemStacks);
                itemStacks.clear();
                final WorldServer minecraftWorld = EntityUtil.getMinecraftWorld(affectedEntity.get());
                if (!items.isEmpty()) {
                    final List<Entity> itemEntities = items.stream().map(data -> data.create(minecraftWorld)).map(EntityUtil::fromNative).collect(Collectors.toList());
                    Sponge.getCauseStackManager().pushCause(affectedEntity.get());
                    final DropItemEvent.Destruct destruct = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), itemEntities);
                    SpongeImpl.postEvent(destruct);
                    Sponge.getCauseStackManager().popCause();
                    if (!destruct.isCancelled()) {
                        final boolean isPlayer = sender instanceof Player;
                        final Player player = isPlayer ? (Player) sender : null;
                        for (Entity entity : destruct.getEntities()) {
                            if (isPlayer) {
                                EntityUtil.toMixin(entity).setCreator(player.getUniqueId());
                            }
                            EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                        }
                    }
                }
            }
        });
    }
}
Also used : Entity(org.spongepowered.api.entity.Entity) ArrayList(java.util.ArrayList) WorldServer(net.minecraft.world.WorldServer) CauseStackManager(org.spongepowered.api.event.CauseStackManager) UUID(java.util.UUID) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) IMixinInventoryPlayer(org.spongepowered.common.interfaces.entity.player.IMixinInventoryPlayer) EntityPlayer(net.minecraft.entity.player.EntityPlayer) Player(org.spongepowered.api.entity.living.player.Player) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) CommandSource(org.spongepowered.api.command.CommandSource) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) IMixinInventoryPlayer(org.spongepowered.common.interfaces.entity.player.IMixinInventoryPlayer) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) EntityPlayer(net.minecraft.entity.player.EntityPlayer) ChangeInventoryEvent(org.spongepowered.api.event.item.inventory.ChangeInventoryEvent) Collection(java.util.Collection) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) Map(java.util.Map) Inventory(org.spongepowered.api.item.inventory.Inventory) Nullable(javax.annotation.Nullable)

Example 2 with ChangeInventoryEvent

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

the class InventoryBasedTransaction method generateEvent.

@Override
public Optional<ChangeInventoryEvent> generateEvent(final PhaseContext<@NonNull ?> context, @Nullable final GameTransaction<@NonNull ?> parent, final ImmutableList<GameTransaction<ChangeInventoryEvent>> gameTransactions, final Cause currentCause) {
    final ImmutableList<InventoryBasedTransaction> containerBasedTransactions = gameTransactions.stream().filter(tx -> tx instanceof InventoryBasedTransaction).map(tx -> (InventoryBasedTransaction) tx).filter(tx -> !tx.used).collect(ImmutableList.toImmutableList());
    final List<SlotTransaction> slotTransactions = containerBasedTransactions.stream().map(InventoryBasedTransaction::getSlotTransactions).flatMap(List::stream).collect(Collectors.toList());
    for (InventoryBasedTransaction transaction : containerBasedTransactions) {
        transaction.used = true;
    }
    final List<Entity> entities = containerBasedTransactions.stream().map(InventoryBasedTransaction::getEntitiesSpawned).flatMap(List::stream).collect(Collectors.toList());
    // TODO on pickup grouping does not work?
    final Map<Slot, List<SlotTransaction>> collected = slotTransactions.stream().collect(Collectors.groupingBy(SlotTransaction::slot));
    slotTransactions.clear();
    collected.values().forEach(list -> {
        final SlotTransaction first = list.get(0);
        if (list.size() > 1) {
            final ItemStackSnapshot last = list.get(list.size() - 1).defaultReplacement();
            slotTransactions.add(new SlotTransaction(first.slot(), first.original(), last));
        } else {
            slotTransactions.add(first);
        }
    });
    return containerBasedTransactions.stream().map(t -> t.createInventoryEvent(slotTransactions, entities, context, currentCause)).filter(Optional::isPresent).map(Optional::get).findFirst();
}
Also used : Inventory(org.spongepowered.api.item.inventory.Inventory) NonNull(org.checkerframework.checker.nullness.qual.NonNull) SpawnEntityTransaction(org.spongepowered.common.event.tracking.context.transaction.world.SpawnEntityTransaction) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) PrettyPrinter(org.spongepowered.common.util.PrettyPrinter) TransactionTypes(org.spongepowered.common.event.tracking.context.transaction.type.TransactionTypes) ArrayList(java.util.ArrayList) MonotonicNonNull(org.checkerframework.checker.nullness.qual.MonotonicNonNull) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) CauseStackManager(org.spongepowered.api.event.CauseStackManager) LinkedList(java.util.LinkedList) Nullable(org.checkerframework.checker.nullness.qual.Nullable) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) Slot(org.spongepowered.api.item.inventory.Slot) 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) GameTransaction(org.spongepowered.common.event.tracking.context.transaction.GameTransaction) PhaseContext(org.spongepowered.common.event.tracking.PhaseContext) ChangeInventoryEvent(org.spongepowered.api.event.item.inventory.ChangeInventoryEvent) PacketPhaseUtil(org.spongepowered.common.event.tracking.phase.packet.PacketPhaseUtil) Optional(java.util.Optional) Collections(java.util.Collections) Entity(org.spongepowered.api.entity.Entity) Optional(java.util.Optional) Slot(org.spongepowered.api.item.inventory.Slot) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) List(java.util.List) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction)

Example 3 with ChangeInventoryEvent

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

the class CloseMenuTransaction method postProcessEvent.

@Override
public void postProcessEvent(final PhaseContext<@NonNull ?> context, final InteractContainerEvent event) {
    if (!this.clientSource) {
        // Server closed send packet to client
        this.player.connection.send(new ClientboundContainerClosePacket(this.player.containerMenu.containerId));
    }
    // Finish closing container
    this.player.containerMenu = this.player.inventoryMenu;
    // And restore cursor if needed
    PacketPhaseUtil.handleCursorRestore(this.player, event.cursorTransaction());
    if (event instanceof ChangeInventoryEvent) {
        PacketPhaseUtil.handleSlotRestore(this.player, this.menu, ((ChangeInventoryEvent) event).transactions(), event.isCancelled());
    }
    // prevent double capture
    this.player.inventoryMenu.broadcastChanges();
}
Also used : ClientboundContainerClosePacket(net.minecraft.network.protocol.game.ClientboundContainerClosePacket) ChangeInventoryEvent(org.spongepowered.api.event.item.inventory.ChangeInventoryEvent)

Aggregations

ChangeInventoryEvent (org.spongepowered.api.event.item.inventory.ChangeInventoryEvent)3 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 Entity (org.spongepowered.api.entity.Entity)2 CauseStackManager (org.spongepowered.api.event.CauseStackManager)2 SpawnEntityEvent (org.spongepowered.api.event.entity.SpawnEntityEvent)2 Inventory (org.spongepowered.api.item.inventory.Inventory)2 SlotTransaction (org.spongepowered.api.item.inventory.transaction.SlotTransaction)2 ImmutableList (com.google.common.collect.ImmutableList)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Optional (java.util.Optional)1 UUID (java.util.UUID)1 BiConsumer (java.util.function.BiConsumer)1 Collectors (java.util.stream.Collectors)1 Nullable (javax.annotation.Nullable)1 EntityPlayer (net.minecraft.entity.player.EntityPlayer)1 ClientboundContainerClosePacket (net.minecraft.network.protocol.game.ClientboundContainerClosePacket)1