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