Search in sources :

Example 1 with BlockTransaction

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

the class BlockEventBasedTransaction method markCancelledTransactions.

@Override
public final boolean markCancelledTransactions(final ChangeBlockEvent.All event, final ImmutableList<? extends GameTransaction<ChangeBlockEvent.All>> blockTransactions) {
    boolean cancelledAny = false;
    if (event.isCancelled()) {
        event.transactions().forEach(BlockTransaction::invalidate);
    }
    for (final Transaction<BlockSnapshot> transaction : event.transactions()) {
        if (!transaction.isValid()) {
            cancelledAny = true;
            for (final GameTransaction<ChangeBlockEvent.All> gameTransaction : blockTransactions) {
                final BlockEventBasedTransaction blockTransaction = (BlockEventBasedTransaction) gameTransaction;
                final Vector3i position = transaction.original().position();
                final BlockPos affectedPosition = blockTransaction.affectedPosition;
                if (position.x() == affectedPosition.getX() && position.y() == affectedPosition.getY() && position.z() == affectedPosition.getZ()) {
                    gameTransaction.markCancelled();
                }
            }
        }
    }
    return cancelledAny;
}
Also used : SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) Vector3i(org.spongepowered.math.vector.Vector3i) BlockPos(net.minecraft.core.BlockPos) BlockTransaction(org.spongepowered.api.block.transaction.BlockTransaction)

Example 2 with BlockTransaction

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

the class BlockEvent_BreakEventMixin_Forge method bridge$createSpongeEvent.

@Override
@Nullable
public Event bridge$createSpongeEvent() {
    final LevelAccessor accessor = this.shadow$getWorld();
    if (accessor instanceof ServerWorld) {
        final ServerWorld serverWorld = (ServerWorld) accessor;
        final BlockTransaction transaction = new BlockTransaction(SpongeBlockSnapshot.BuilderImpl.pooled().world(serverWorld.key()).position(VecHelper.toVector3i(this.shadow$getPos())).blockState((BlockState) this.shadow$getState()).build(), SpongeBlockSnapshot.BuilderImpl.pooled().world(serverWorld.key()).position(VecHelper.toVector3i(this.shadow$getPos())).blockState(BlockState.builder().blockType(BlockTypes.AIR.get()).build()).build(), Operations.BREAK.get());
        return SpongeEventFactory.createChangeBlockEventAll(PhaseTracker.getCauseStackManager().currentCause(), Collections.singletonList(transaction), serverWorld);
    }
    return null;
}
Also used : ServerWorld(org.spongepowered.api.world.server.ServerWorld) LevelAccessor(net.minecraft.world.level.LevelAccessor) BlockTransaction(org.spongepowered.api.block.transaction.BlockTransaction) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 3 with BlockTransaction

use of org.spongepowered.api.block.transaction.BlockTransaction 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 4 with BlockTransaction

use of org.spongepowered.api.block.transaction.BlockTransaction 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

BlockTransaction (org.spongepowered.api.block.transaction.BlockTransaction)4 BlockPos (net.minecraft.core.BlockPos)3 ServerWorld (org.spongepowered.api.world.server.ServerWorld)3 SpongeBlockSnapshot (org.spongepowered.common.block.SpongeBlockSnapshot)3 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 NonNull (org.checkerframework.checker.nullness.qual.NonNull)2 Nullable (org.checkerframework.checker.nullness.qual.Nullable)2 ResourceKey (org.spongepowered.api.ResourceKey)2 BlockSnapshot (org.spongepowered.api.block.BlockSnapshot)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 SpongeCommon (org.spongepowered.common.SpongeCommon)2 SpongeServer (org.spongepowered.common.SpongeServer)2