Search in sources :

Example 1 with Operation

use of org.spongepowered.api.block.transaction.Operation in project SpongeCommon by SpongePowered.

the class BlockTransactionType method consumeEventsAndMarker.

@Override
protected void consumeEventsAndMarker(PhaseContext<@NonNull ?> context, final Collection<? extends ChangeBlockEvent.All> changeBlockEvents) {
    final Multimap<ResourceKey, ChangeBlockEvent.All> eventsByWorld = LinkedListMultimap.create();
    changeBlockEvents.forEach(event -> eventsByWorld.put(event.world().key(), event));
    eventsByWorld.asMap().forEach((key, events) -> {
        final Optional<ServerWorld> serverWorld = ((SpongeServer) SpongeCommon.server()).worldManager().world(key);
        if (!serverWorld.isPresent()) {
            return;
        }
        final ListMultimap<BlockPos, SpongeBlockSnapshot> positions = LinkedListMultimap.create();
        // Gather transactions that were valid
        events.stream().filter(event -> !event.isCancelled()).flatMap(event -> event.transactions().stream()).filter(BlockTransaction::isValid).forEach(transactions -> {
            // Then "put" the most recent transactions such that we have a complete rebuild of
            // each position according to what originally existed and then
            // the ultimate final block on that position
            final SpongeBlockSnapshot original = (SpongeBlockSnapshot) transactions.original();
            positions.put(original.getBlockPos(), original);
            positions.put(original.getBlockPos(), (SpongeBlockSnapshot) transactions.finalReplacement());
        });
        // just return.
        if (positions.isEmpty()) {
            return;
        }
        final ImmutableList<BlockTransactionReceipt> transactions = positions.asMap().values().stream().map(spongeBlockSnapshots -> {
            final List<SpongeBlockSnapshot> snapshots = new ArrayList<>(spongeBlockSnapshots);
            if (snapshots.isEmpty() || snapshots.size() < 2) {
                // Error case
                return Optional.<BlockTransactionReceipt>empty();
            }
            final SpongeBlockSnapshot original = snapshots.get(0);
            final SpongeBlockSnapshot result = snapshots.get(snapshots.size() - 1);
            final Operation operation = context.getBlockOperation(original, result);
            final BlockTransactionReceipt eventTransaction = new BlockTransactionReceipt(original, result, operation);
            context.postBlockTransactionApplication(original.blockChange, eventTransaction);
            return Optional.of(eventTransaction);
        }).filter(Optional::isPresent).map(Optional::get).collect(ImmutableList.toImmutableList());
        final Cause cause = PhaseTracker.getInstance().currentCause();
        SpongeCommon.post(SpongeEventFactory.createChangeBlockEventPost(cause, transactions, serverWorld.get()));
    });
}
Also used : LinkedListMultimap(com.google.common.collect.LinkedListMultimap) NonNull(org.checkerframework.checker.nullness.qual.NonNull) ServerWorld(org.spongepowered.api.world.server.ServerWorld) ListMultimap(com.google.common.collect.ListMultimap) ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) SpongeServer(org.spongepowered.common.SpongeServer) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Collection(java.util.Collection) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) SpongeCommon(org.spongepowered.common.SpongeCommon) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) Multimap(com.google.common.collect.Multimap) Cause(org.spongepowered.api.event.Cause) ArrayList(java.util.ArrayList) BlockTransactionReceipt(org.spongepowered.api.block.transaction.BlockTransactionReceipt) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) BlockPos(net.minecraft.core.BlockPos) PhaseContext(org.spongepowered.common.event.tracking.PhaseContext) BlockTransaction(org.spongepowered.api.block.transaction.BlockTransaction) ResourceKey(org.spongepowered.api.ResourceKey) Optional(java.util.Optional) Operation(org.spongepowered.api.block.transaction.Operation) BlockTransactionReceipt(org.spongepowered.api.block.transaction.BlockTransactionReceipt) Optional(java.util.Optional) Operation(org.spongepowered.api.block.transaction.Operation) ResourceKey(org.spongepowered.api.ResourceKey) ServerWorld(org.spongepowered.api.world.server.ServerWorld) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) Cause(org.spongepowered.api.event.Cause) BlockPos(net.minecraft.core.BlockPos) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList)

Example 2 with Operation

use of org.spongepowered.api.block.transaction.Operation in project SpongeCommon by SpongePowered.

the class BlockEventBasedTransaction method generateEvent.

@Override
public final Optional<ChangeBlockEvent.All> generateEvent(final PhaseContext<@NonNull ?> context, @Nullable final GameTransaction<@NonNull ?> parent, final ImmutableList<GameTransaction<ChangeBlockEvent.All>> transactions, final Cause currentCause) {
    final Optional<ServerWorld> o = ((SpongeServer) SpongeCommon.server()).worldManager().world(this.worldKey);
    if (!o.isPresent()) {
        return Optional.empty();
    }
    final ListMultimap<BlockPos, SpongeBlockSnapshot> positions = LinkedListMultimap.create();
    for (final GameTransaction<@NonNull ?> transaction : transactions) {
        final BlockEventBasedTransaction blockTransaction = (BlockEventBasedTransaction) transaction;
        if (!positions.containsKey(blockTransaction.affectedPosition)) {
            positions.put(blockTransaction.affectedPosition, blockTransaction.getOriginalSnapshot());
        }
        if (blockTransaction.getResultingSnapshot() != null) {
            positions.put(blockTransaction.affectedPosition, blockTransaction.getResultingSnapshot());
        }
    }
    final ImmutableList<BlockTransaction> eventTransactions = positions.asMap().values().stream().map(spongeBlockSnapshots -> {
        final List<SpongeBlockSnapshot> snapshots = new ArrayList<>(spongeBlockSnapshots);
        if (snapshots.isEmpty() || snapshots.size() < 2) {
            // Error case
            return Optional.<BlockTransaction>empty();
        }
        final SpongeBlockSnapshot original = snapshots.get(0);
        final SpongeBlockSnapshot result = snapshots.get(snapshots.size() - 1);
        final ImmutableList<BlockSnapshot> intermediary;
        if (snapshots.size() > 2) {
            intermediary = ImmutableList.copyOf(snapshots.subList(1, snapshots.size() - 2));
        } else {
            intermediary = ImmutableList.of();
        }
        final Operation operation = context.getBlockOperation(original, result);
        final BlockTransaction eventTransaction = new BlockTransaction(original, result, intermediary, operation);
        return Optional.of(eventTransaction);
    }).filter(Optional::isPresent).map(Optional::get).collect(ImmutableList.toImmutableList());
    if (eventTransactions.isEmpty()) {
        return Optional.empty();
    }
    return Optional.of(SpongeEventFactory.createChangeBlockEventAll(currentCause, eventTransactions, o.get()));
}
Also used : NonNull(org.checkerframework.checker.nullness.qual.NonNull) ServerWorld(org.spongepowered.api.world.server.ServerWorld) ListMultimap(com.google.common.collect.ListMultimap) ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) SpongeServer(org.spongepowered.common.SpongeServer) BlockState(net.minecraft.world.level.block.state.BlockState) TransactionTypes(org.spongepowered.common.event.tracking.context.transaction.type.TransactionTypes) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) BlockTransaction(org.spongepowered.api.block.transaction.BlockTransaction) ResourceKey(org.spongepowered.api.ResourceKey) Nullable(org.checkerframework.checker.nullness.qual.Nullable) Transaction(org.spongepowered.api.data.Transaction) LinkedListMultimap(com.google.common.collect.LinkedListMultimap) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) SpongeCommon(org.spongepowered.common.SpongeCommon) Cause(org.spongepowered.api.event.Cause) List(java.util.List) GameTransaction(org.spongepowered.common.event.tracking.context.transaction.GameTransaction) WorldBasedTransaction(org.spongepowered.common.event.tracking.context.transaction.world.WorldBasedTransaction) BlockPos(net.minecraft.core.BlockPos) PhaseContext(org.spongepowered.common.event.tracking.PhaseContext) Optional(java.util.Optional) Operation(org.spongepowered.api.block.transaction.Operation) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) Vector3i(org.spongepowered.math.vector.Vector3i) Optional(java.util.Optional) ImmutableList(com.google.common.collect.ImmutableList) Operation(org.spongepowered.api.block.transaction.Operation) ServerWorld(org.spongepowered.api.world.server.ServerWorld) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) BlockPos(net.minecraft.core.BlockPos) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) BlockTransaction(org.spongepowered.api.block.transaction.BlockTransaction)

Aggregations

ImmutableList (com.google.common.collect.ImmutableList)2 LinkedListMultimap (com.google.common.collect.LinkedListMultimap)2 ListMultimap (com.google.common.collect.ListMultimap)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Optional (java.util.Optional)2 BlockPos (net.minecraft.core.BlockPos)2 NonNull (org.checkerframework.checker.nullness.qual.NonNull)2 ResourceKey (org.spongepowered.api.ResourceKey)2 BlockTransaction (org.spongepowered.api.block.transaction.BlockTransaction)2 Operation (org.spongepowered.api.block.transaction.Operation)2 Cause (org.spongepowered.api.event.Cause)2 SpongeEventFactory (org.spongepowered.api.event.SpongeEventFactory)2 ChangeBlockEvent (org.spongepowered.api.event.block.ChangeBlockEvent)2 ServerWorld (org.spongepowered.api.world.server.ServerWorld)2 SpongeCommon (org.spongepowered.common.SpongeCommon)2 SpongeServer (org.spongepowered.common.SpongeServer)2 SpongeBlockSnapshot (org.spongepowered.common.block.SpongeBlockSnapshot)2 PhaseContext (org.spongepowered.common.event.tracking.PhaseContext)2 Multimap (com.google.common.collect.Multimap)1