use of net.minecraft.world.level.BlockGetter in project Cyclic by Lothrazar.
the class GlassConnectedBlock method getStateForPlacement.
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
BlockGetter world = context.getLevel();
BlockPos pos = context.getClickedPos();
return super.getStateForPlacement(context).setValue(CONNECTED_DOWN, this.isSideConnectable(world, pos, Direction.DOWN)).setValue(CONNECTED_EAST, this.isSideConnectable(world, pos, Direction.EAST)).setValue(CONNECTED_NORTH, this.isSideConnectable(world, pos, Direction.NORTH)).setValue(CONNECTED_SOUTH, this.isSideConnectable(world, pos, Direction.SOUTH)).setValue(CONNECTED_UP, this.isSideConnectable(world, pos, Direction.UP)).setValue(CONNECTED_WEST, this.isSideConnectable(world, pos, Direction.WEST));
}
use of net.minecraft.world.level.BlockGetter in project ElevatorMod by VsnGamer.
the class ElevatorHandler method tryTeleport.
private static void tryTeleport(LocalPlayer player, Direction facing) {
BlockGetter world = player.getCommandSenderWorld();
BlockPos fromPos = getOriginElevator(player);
if (fromPos == null)
return;
BlockPos.MutableBlockPos toPos = fromPos.mutable();
ElevatorBlock fromElevator;
fromElevator = (ElevatorBlock) world.getBlockState(fromPos).getBlock();
while (true) {
toPos.setY(toPos.getY() + facing.getStepY());
if (world.isOutsideBuildHeight(toPos) || Math.abs(toPos.getY() - fromPos.getY()) > ModConfig.GENERAL.range.get())
break;
ElevatorBlock toElevator = TeleportHandler.getElevator(world.getBlockState(toPos));
if (toElevator != null && TeleportHandler.isBlocked(world, toPos)) {
if (!ModConfig.GENERAL.sameColor.get() || fromElevator.getColor() == toElevator.getColor()) {
NetworkHandler.INSTANCE.sendToServer(new TeleportRequest(fromPos, toPos));
break;
}
}
}
}
use of net.minecraft.world.level.BlockGetter in project Starlight by PaperMC.
the class SkyStarLightEngine method lightChunk.
@Override
protected void lightChunk(final LightChunkGetter lightAccess, final ChunkAccess chunk, final boolean needsEdgeChecks) {
this.rewriteNibbleCacheForSkylight(chunk);
Arrays.fill(this.nullPropagationCheckCache, false);
final BlockGetter world = lightAccess.getLevel();
final ChunkPos chunkPos = chunk.getPos();
final int chunkX = chunkPos.x;
final int chunkZ = chunkPos.z;
final LevelChunkSection[] sections = chunk.getSections();
int highestNonEmptySection = this.maxSection;
while (highestNonEmptySection == (this.minSection - 1) || sections[highestNonEmptySection - this.minSection] == null || sections[highestNonEmptySection - this.minSection].hasOnlyAir()) {
this.checkNullSection(chunkX, highestNonEmptySection, chunkZ, false);
// check neighbours to see if we need to propagate into them
for (final AxisDirection direction : ONLY_HORIZONTAL_DIRECTIONS) {
final int neighbourX = chunkX + direction.x;
final int neighbourZ = chunkZ + direction.z;
final SWMRNibbleArray neighbourNibble = this.getNibbleFromCache(neighbourX, highestNonEmptySection, neighbourZ);
if (neighbourNibble == null) {
// most of the time we fall here
continue;
}
// it looks like we need to propagate into the neighbour
final int incX;
final int incZ;
final int startX;
final int startZ;
if (direction.x != 0) {
// x direction
incX = 0;
incZ = 1;
if (direction.x < 0) {
// negative
startX = chunkX << 4;
} else {
startX = chunkX << 4 | 15;
}
startZ = chunkZ << 4;
} else {
// z direction
incX = 1;
incZ = 0;
if (direction.z < 0) {
// negative
startZ = chunkZ << 4;
} else {
startZ = chunkZ << 4 | 15;
}
startX = chunkX << 4;
}
final int encodeOffset = this.coordinateOffset;
// we only want to check in this direction
final long propagateDirection = 1L << direction.ordinal();
for (int currY = highestNonEmptySection << 4, maxY = currY | 15; currY <= maxY; ++currY) {
for (int i = 0, currX = startX, currZ = startZ; i < 16; ++i, currX += incX, currZ += incZ) {
this.appendToIncreaseQueue(((currX + (currZ << 6) + (currY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) | // we know we're at full lit here
(15L << (6 + 6 + 16)) | (propagateDirection << (6 + 6 + 16 + 4)));
}
}
}
if (highestNonEmptySection-- == (this.minSection - 1)) {
break;
}
}
if (highestNonEmptySection >= this.minSection) {
// fill out our other sources
final int minX = chunkPos.x << 4;
final int maxX = chunkPos.x << 4 | 15;
final int minZ = chunkPos.z << 4;
final int maxZ = chunkPos.z << 4 | 15;
final int startY = highestNonEmptySection << 4 | 15;
for (int currZ = minZ; currZ <= maxZ; ++currZ) {
for (int currX = minX; currX <= maxX; ++currX) {
this.tryPropagateSkylight(world, currX, startY + 1, currZ, false, false);
}
}
}
if (needsEdgeChecks) {
// not required to propagate here, but this will reduce the hit of the edge checks
this.performLightIncrease(lightAccess);
for (int y = highestNonEmptySection; y >= this.minLightSection; --y) {
this.checkNullSection(chunkX, y, chunkZ, false);
}
// no need to rewrite the nibble cache again
super.checkChunkEdges(lightAccess, chunk, this.minLightSection, highestNonEmptySection);
} else {
for (int y = highestNonEmptySection; y >= this.minLightSection; --y) {
this.checkNullSection(chunkX, y, chunkZ, false);
}
this.propagateNeighbourLevels(lightAccess, chunk, this.minLightSection, highestNonEmptySection);
this.performLightIncrease(lightAccess);
}
}
use of net.minecraft.world.level.BlockGetter in project Starlight by PaperMC.
the class SkyStarLightEngine method propagateBlockChanges.
@Override
protected void propagateBlockChanges(final LightChunkGetter lightAccess, final ChunkAccess atChunk, final Set<BlockPos> positions) {
this.rewriteNibbleCacheForSkylight(atChunk);
Arrays.fill(this.nullPropagationCheckCache, false);
final BlockGetter world = lightAccess.getLevel();
final int chunkX = atChunk.getPos().x;
final int chunkZ = atChunk.getPos().z;
final int heightMapOffset = chunkX * -16 + (chunkZ * (-16 * 16));
// setup heightmap for changes
for (final BlockPos pos : positions) {
final int index = pos.getX() + (pos.getZ() << 4) + heightMapOffset;
final int curr = this.heightMapBlockChange[index];
if (pos.getY() > curr) {
this.heightMapBlockChange[index] = pos.getY();
}
}
// now we can recalculate the sources for the changed columns
for (int index = 0; index < (16 * 16); ++index) {
final int maxY = this.heightMapBlockChange[index];
if (maxY == Integer.MIN_VALUE) {
// not changed
continue;
}
// restore default for next caller
this.heightMapBlockChange[index] = Integer.MIN_VALUE;
final int columnX = (index & 15) | (chunkX << 4);
final int columnZ = (index >>> 4) | (chunkZ << 4);
// try and propagate from the above y
// delay light set until after processing all sources to setup
final int maxPropagationY = this.tryPropagateSkylight(world, columnX, maxY, columnZ, true, true);
// maxPropagationY is now the highest block that could not be propagated to
// remove all sources below that are 15
final long propagateDirection = AxisDirection.POSITIVE_Y.everythingButThisDirection;
final int encodeOffset = this.coordinateOffset;
if (this.getLightLevelExtruded(columnX, maxPropagationY, columnZ) == 15) {
// ensure section is checked
this.checkNullSection(columnX >> 4, maxPropagationY >> 4, columnZ >> 4, true);
for (int currY = maxPropagationY; currY >= (this.minLightSection << 4); --currY) {
if ((currY & 15) == 15) {
// ensure section is checked
this.checkNullSection(columnX >> 4, (currY >> 4), columnZ >> 4, true);
}
// ensure section below is always checked
final SWMRNibbleArray nibble = this.getNibbleFromCache(columnX >> 4, currY >> 4, columnZ >> 4);
if (nibble == null) {
// advance currY to the the top of the section below
currY = (currY) & (~15);
// end up there
continue;
}
if (nibble.getUpdating(columnX, currY, columnZ) != 15) {
break;
}
// delay light set until after processing all sources to setup
this.appendToDecreaseQueue(((columnX + (columnZ << 6) + (currY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) | (15L << (6 + 6 + 16)) | (propagateDirection << (6 + 6 + 16 + 4)));
}
}
}
// delayed light sets are processed here, and must be processed before checkBlock as checkBlock reads
// immediate light value
this.processDelayedIncreases();
this.processDelayedDecreases();
for (final BlockPos pos : positions) {
this.checkBlock(lightAccess, pos.getX(), pos.getY(), pos.getZ());
}
this.performLightDecrease(lightAccess);
}
use of net.minecraft.world.level.BlockGetter in project Starlight by PaperMC.
the class StarLightEngine method performLightIncrease.
protected final void performLightIncrease(final LightChunkGetter lightAccess) {
final BlockGetter world = lightAccess.getLevel();
long[] queue = this.increaseQueue;
int queueReadIndex = 0;
int queueLength = this.increaseQueueInitialLength;
this.increaseQueueInitialLength = 0;
final int decodeOffsetX = -this.encodeOffsetX;
final int decodeOffsetY = -this.encodeOffsetY;
final int decodeOffsetZ = -this.encodeOffsetZ;
final int encodeOffset = this.coordinateOffset;
final int sectionOffset = this.chunkSectionIndexOffset;
while (queueReadIndex < queueLength) {
final long queueValue = queue[queueReadIndex++];
final int posX = ((int) queueValue & 63) + decodeOffsetX;
final int posZ = (((int) queueValue >>> 6) & 63) + decodeOffsetZ;
final int posY = (((int) queueValue >>> 12) & ((1 << 16) - 1)) + decodeOffsetY;
final int propagatedLightLevel = (int) ((queueValue >>> (6 + 6 + 16)) & 0xFL);
final AxisDirection[] checkDirections = OLD_CHECK_DIRECTIONS[(int) ((queueValue >>> (6 + 6 + 16 + 4)) & 63L)];
if ((queueValue & FLAG_RECHECK_LEVEL) != 0L) {
if (this.getLightLevel(posX, posY, posZ) != propagatedLightLevel) {
// not at the level we expect, so something changed.
continue;
}
} else if ((queueValue & FLAG_WRITE_LEVEL) != 0L) {
// these are used to restore block sources after a propagation decrease
this.setLightLevel(posX, posY, posZ, propagatedLightLevel);
}
if ((queueValue & FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) == 0L) {
// we don't need to worry about our state here.
for (final AxisDirection propagate : checkDirections) {
final int offX = posX + propagate.x;
final int offY = posY + propagate.y;
final int offZ = posZ + propagate.z;
final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset;
final int localIndex = (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8);
final SWMRNibbleArray currentNibble = this.nibbleCache[sectionIndex];
final int currentLevel;
if (currentNibble == null || (currentLevel = currentNibble.getUpdating(localIndex)) >= (propagatedLightLevel - 1)) {
// already at the level we want or unloaded
continue;
}
final BlockState blockState = this.getBlockState(sectionIndex, localIndex);
if (blockState == null) {
continue;
}
final int opacityCached = ((ExtendedAbstractBlockState) blockState).getOpacityIfCached();
if (opacityCached != -1) {
final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached);
if (targetLevel > currentLevel) {
currentNibble.set(localIndex, targetLevel);
this.postLightUpdate(offX, offY, offZ);
if (targetLevel > 1) {
if (queueLength >= queue.length) {
queue = this.resizeIncreaseQueue();
}
queue[queueLength++] = ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) | ((targetLevel & 0xFL) << (6 + 6 + 16)) | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4));
continue;
}
}
continue;
} else {
this.mutablePos1.set(offX, offY, offZ);
long flags = 0;
if (((ExtendedAbstractBlockState) blockState).isConditionallyFullOpaque()) {
final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms);
if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) {
continue;
}
flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS;
}
final int opacity = blockState.getLightBlock(world, this.mutablePos1);
final int targetLevel = propagatedLightLevel - Math.max(1, opacity);
if (targetLevel <= currentLevel) {
continue;
}
currentNibble.set(localIndex, targetLevel);
this.postLightUpdate(offX, offY, offZ);
if (targetLevel > 1) {
if (queueLength >= queue.length) {
queue = this.resizeIncreaseQueue();
}
queue[queueLength++] = ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) | ((targetLevel & 0xFL) << (6 + 6 + 16)) | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) | (flags);
}
continue;
}
}
} else {
// we actually need to worry about our state here
final BlockState fromBlock = this.getBlockState(posX, posY, posZ);
this.mutablePos2.set(posX, posY, posZ);
for (final AxisDirection propagate : checkDirections) {
final int offX = posX + propagate.x;
final int offY = posY + propagate.y;
final int offZ = posZ + propagate.z;
final VoxelShape fromShape = (((ExtendedAbstractBlockState) fromBlock).isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty();
if (fromShape != Shapes.empty() && Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) {
continue;
}
final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset;
final int localIndex = (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8);
final SWMRNibbleArray currentNibble = this.nibbleCache[sectionIndex];
final int currentLevel;
if (currentNibble == null || (currentLevel = currentNibble.getUpdating(localIndex)) >= (propagatedLightLevel - 1)) {
// already at the level we want
continue;
}
final BlockState blockState = this.getBlockState(sectionIndex, localIndex);
if (blockState == null) {
continue;
}
final int opacityCached = ((ExtendedAbstractBlockState) blockState).getOpacityIfCached();
if (opacityCached != -1) {
final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached);
if (targetLevel > currentLevel) {
currentNibble.set(localIndex, targetLevel);
this.postLightUpdate(offX, offY, offZ);
if (targetLevel > 1) {
if (queueLength >= queue.length) {
queue = this.resizeIncreaseQueue();
}
queue[queueLength++] = ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) | ((targetLevel & 0xFL) << (6 + 6 + 16)) | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4));
continue;
}
}
continue;
} else {
this.mutablePos1.set(offX, offY, offZ);
long flags = 0;
if (((ExtendedAbstractBlockState) blockState).isConditionallyFullOpaque()) {
final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms);
if (Shapes.faceShapeOccludes(fromShape, cullingFace)) {
continue;
}
flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS;
}
final int opacity = blockState.getLightBlock(world, this.mutablePos1);
final int targetLevel = propagatedLightLevel - Math.max(1, opacity);
if (targetLevel <= currentLevel) {
continue;
}
currentNibble.set(localIndex, targetLevel);
this.postLightUpdate(offX, offY, offZ);
if (targetLevel > 1) {
if (queueLength >= queue.length) {
queue = this.resizeIncreaseQueue();
}
queue[queueLength++] = ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) | ((targetLevel & 0xFL) << (6 + 6 + 16)) | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) | (flags);
}
continue;
}
}
}
}
}
Aggregations