use of org.spongepowered.common.event.tracking.context.transaction.pipeline.ChunkPipeline 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();
}
use of org.spongepowered.common.event.tracking.context.transaction.pipeline.ChunkPipeline in project SpongeCommon by SpongePowered.
the class ServerLevelMixin_Tracker method bridge$makePipeline.
private WorldPipeline.Builder bridge$makePipeline(final BlockPos pos, final BlockState currentState, final BlockState newState, final LevelChunk chunk, final SpongeBlockChangeFlag spongeFlag, final int limit) {
final TrackedLevelChunkBridge mixinChunk = (TrackedLevelChunkBridge) chunk;
// Then build and use the BlockPipeline
final ChunkPipeline chunkPipeline = mixinChunk.bridge$createChunkPipeline(pos, newState, currentState, spongeFlag, limit);
final WorldPipeline.Builder worldPipelineBuilder = WorldPipeline.builder(chunkPipeline);
worldPipelineBuilder.addEffect((pipeline, oldState, newState1, flag1, cursorLimit) -> {
if (oldState == null) {
return EffectResult.NULL_RETURN;
}
return EffectResult.NULL_PASS;
}).addEffect(UpdateLightSideEffect.getInstance()).addEffect(CheckBlockPostPlacementIsSameEffect.getInstance()).addEffect(UpdateWorldRendererEffect.getInstance()).addEffect(NotifyClientEffect.getInstance()).addEffect(NotifyNeighborSideEffect.getInstance()).addEffect(UpdateConnectingBlocksEffect.getInstance());
return worldPipelineBuilder;
}
Aggregations