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