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);
}
}
}
}
});
}
}
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();
}
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();
}
Aggregations