use of net.minecraft.world.level.chunk.LevelChunkSection in project SpongeCommon by SpongePowered.
the class VolumeStreamUtils method getElementByPosition.
private static <T> Function<ChunkAccess, Stream<Map.Entry<BlockPos, T>>> getElementByPosition(final TriFunction<ChunkAccess, LevelChunkSection, BlockPos, T> elementAccessor, final Vector3i min, final Vector3i max) {
// Build the min and max
final ChunkCursor minCursor = new ChunkCursor(min);
final ChunkCursor maxCursor = new ChunkCursor(max);
return chunk -> {
final ChunkPos pos = chunk.getPos();
final int xStart = pos.x == minCursor.chunkX ? minCursor.xOffset : 0;
// 16 because IntStream.range is upper range exclusive
final int xEnd = pos.x == maxCursor.chunkX ? maxCursor.xOffset + 1 : 16;
final int zStart = pos.z == minCursor.chunkZ ? minCursor.zOffset : 0;
// 16 because IntStream.range is upper range exclusive
final int zEnd = pos.z == maxCursor.chunkZ ? maxCursor.zOffset + 1 : 16;
final int chunkMinX = pos.x << 4;
final int chunkMinZ = pos.z << 4;
return Arrays.stream(chunk.getSections()).filter(Objects::nonNull).filter(chunkSection -> chunkSection.bottomBlockY() >= minCursor.ySection && chunkSection.bottomBlockY() <= maxCursor.ySection).flatMap(chunkSection -> IntStream.range(zStart, zEnd).mapToObj(z -> IntStream.range(xStart, xEnd).mapToObj(x -> {
final int sectionY = chunkSection.bottomBlockY();
final int yStart = sectionY == minCursor.ySection ? minCursor.yOffset : 0;
// plus 1 because of IntStream range exclusive
final int yEnd = sectionY == maxCursor.ySection ? maxCursor.yOffset + 1 : 16;
return IntStream.range(yStart, yEnd).mapToObj(y -> {
final int adjustedX = x + chunkMinX;
final int adjustedY = y + sectionY;
final int adjustedZ = z + chunkMinZ;
final BlockPos blockPos = new BlockPos(adjustedX, adjustedY, adjustedZ);
final T apply = Objects.requireNonNull(elementAccessor.apply(chunk, chunkSection, blockPos), "Element cannot be null");
return new AbstractMap.SimpleEntry<>(blockPos, apply);
});
})).flatMap(Function.identity()).flatMap(Function.identity()));
};
}
use of net.minecraft.world.level.chunk.LevelChunkSection 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 net.minecraft.world.level.chunk.LevelChunkSection in project Denizen-For-Bukkit by DenizenScript.
the class ChunkHelperImpl method setAllBiomes.
@Override
public void setAllBiomes(Chunk chunk, BiomeNMS biome) {
Biome nmsBiome = ((BiomeNMSImpl) biome).biomeBase;
LevelChunk nmsChunk = ((CraftChunk) chunk).getHandle();
ChunkPos chunkcoordintpair = nmsChunk.getPos();
int i = QuartPos.fromBlock(chunkcoordintpair.getMinBlockX());
int j = QuartPos.fromBlock(chunkcoordintpair.getMinBlockZ());
LevelHeightAccessor levelheightaccessor = nmsChunk.getHeightAccessorForGeneration();
for (int k = levelheightaccessor.getMinSection(); k < levelheightaccessor.getMaxSection(); ++k) {
LevelChunkSection chunksection = nmsChunk.getSection(nmsChunk.getSectionIndexFromSectionY(k));
PalettedContainer<Biome> datapaletteblock = chunksection.getBiomes();
datapaletteblock.acquire();
for (int l = 0; l < 4; ++l) {
for (int i1 = 0; i1 < 4; ++i1) {
for (int j1 = 0; j1 < 4; ++j1) {
datapaletteblock.getAndSetUnchecked(l, i1, j1, nmsBiome);
}
}
}
datapaletteblock.release();
}
}
use of net.minecraft.world.level.chunk.LevelChunkSection in project SpongeCommon by SpongePowered.
the class TileEntityPipeline method kickOff.
public static Builder kickOff(final ServerLevel world, final BlockPos pos) {
final WeakReference<ServerLevel> worldRef = new WeakReference<>(world);
final LevelChunk chunk = world.getChunkAt(pos);
final WeakReference<LevelChunk> chunkRef = new WeakReference<>(chunk);
final WeakReference<LevelChunkSection> sectionRef = new WeakReference<>(chunk.getSections()[pos.getY() >> 4]);
final Supplier<ServerLevel> worldSupplier = () -> Objects.requireNonNull(worldRef.get(), "ServerWorld de-referenced");
final Supplier<LevelChunk> chunkSupplier = () -> Objects.requireNonNull(chunkRef.get(), "Chunk de-referenced");
final Supplier<LevelChunkSection> chunkSectionSupplier = () -> Objects.requireNonNull(sectionRef.get(), "ChunkSection de-referenced");
return TileEntityPipeline.builder().chunk(chunkSupplier).world(worldSupplier).chunkSection(chunkSectionSupplier);
}
use of net.minecraft.world.level.chunk.LevelChunkSection in project SpongeCommon by SpongePowered.
the class CheckBlockPostPlacementIsSameEffect method processSideEffect.
@Override
public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, final SpongeBlockChangeFlag flag, final int limit) {
final LevelChunkSection chunkSection = pipeline.getAffectedSection();
final int x = oldState.pos.getX() & 15;
final int y = oldState.pos.getY() & 15;
final int z = oldState.pos.getZ() & 15;
final BlockState currentState = chunkSection.getBlockState(x, y, z);
if (currentState.getBlock() != newState.getBlock()) {
return EffectResult.NULL_RETURN;
}
return EffectResult.NULL_PASS;
}
Aggregations