use of org.spongepowered.common.event.tracking.context.transaction.block.ChangeBlock in project SpongeCommon by SpongePowered.
the class TransactionSink method logBlockChange.
default ChangeBlock logBlockChange(final SpongeBlockSnapshot originalBlockSnapshot, final BlockState newState, final BlockChangeFlag flags) {
final ChangeBlock changeBlock = new ChangeBlock(originalBlockSnapshot, newState, (SpongeBlockChangeFlag) flags);
this.logTransaction(changeBlock);
return changeBlock;
}
use of org.spongepowered.common.event.tracking.context.transaction.block.ChangeBlock in project SpongeCommon by SpongePowered.
the class LevelChunkMixin_Tracker method bridge$createChunkPipeline.
/**
* Technically a full overwrite for {@link LevelChunk#setBlockState(BlockPos, BlockState, boolean)}
* and due to Sponge's hijacking of {@link ServerLevel#setBlock(BlockPos, BlockState, int)},
* it needs to be able to record transactions when necessary. This implementation allows for us to
* further specify the types of transactions and what proxies are needing to set up where.
*
* @param pos The position changing
* @param newState The new state
* @param currentState The current state - passed in from either chunk or world
* @param flag The sponge change flag, converted from an int to a proper struct
* @return The changed block state if not null
* @author gabizou - January 13th, 2020 - Minecraft 1.14.3
*/
@Override
@NonNull
public ChunkPipeline bridge$createChunkPipeline(final BlockPos pos, final BlockState newState, final BlockState currentState, final SpongeBlockChangeFlag flag, final int limit) {
final boolean isFake = ((LevelBridge) this.level).bridge$isFake();
if (isFake) {
throw new IllegalStateException("Cannot call ChunkBridge.bridge$buildChunkPipeline in non-Server managed worlds");
}
// int i = pos.getX() & 15;
final int xPos = pos.getX() & 15;
// int j = pos.getY();
final int yPos = pos.getY();
// int k = pos.getZ() & 15;
final int zPos = pos.getZ() & 15;
// Sponge - get the moving flag from our flag construct
LevelChunkSection chunksection = this.sections[yPos >> 4];
if (chunksection == LevelChunkMixin_Tracker.EMPTY_SECTION) {
if (newState.isAir()) {
return ChunkPipeline.nullReturn((LevelChunk) (Object) this, (ServerLevel) this.level);
}
chunksection = new LevelChunkSection(yPos >> 4 << 4);
this.sections[yPos >> 4] = chunksection;
}
// Sponge Start - Build out the BlockTransaction
final PhaseContext<@NonNull ?> context = PhaseTracker.getInstance().getPhaseContext();
@Nullable final BlockEntity existing = this.shadow$getBlockEntity(pos, LevelChunk.EntityCreationType.CHECK);
// Build a transaction maybe?
final WeakReference<ServerLevel> ref = new WeakReference<>((ServerLevel) this.level);
final SpongeBlockSnapshot snapshot = TrackingUtil.createPooledSnapshot(currentState, pos, flag, limit, existing, () -> Objects.requireNonNull(ref.get(), "ServerWorld dereferenced"), Optional::empty, Optional::empty);
// Pulled up from below
final ChangeBlock transaction = context.createTransaction(snapshot, newState, flag);
snapshot.blockChange = context.associateBlockChangeWithSnapshot(newState, currentState);
if (((BlockStateBridge) snapshot.state()).bridge$hasTileEntity() && (snapshot.blockChange == BlockChange.BREAK || snapshot.blockChange == BlockChange.MODIFY)) {
transaction.queuedRemoval = existing;
}
final ChunkPipeline.Builder builder = ChunkPipeline.builder().kickOff(transaction).chunk((LevelChunk) (Object) this).chunkSection(chunksection).world((ServerLevel) this.level);
// Populate the effects
transaction.populateChunkEffects(builder);
return builder.build();
}
Aggregations