Search in sources :

Example 6 with BlockGetter

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));
}
Also used : BlockGetter(net.minecraft.world.level.BlockGetter) BlockPos(net.minecraft.core.BlockPos)

Example 7 with BlockGetter

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;
            }
        }
    }
}
Also used : ElevatorBlock(xyz.vsngamer.elevatorid.blocks.ElevatorBlock) BlockGetter(net.minecraft.world.level.BlockGetter) BlockPos(net.minecraft.core.BlockPos) TeleportRequest(xyz.vsngamer.elevatorid.network.TeleportRequest)

Example 8 with BlockGetter

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);
    }
}
Also used : BlockGetter(net.minecraft.world.level.BlockGetter) LevelChunkSection(net.minecraft.world.level.chunk.LevelChunkSection) ChunkPos(net.minecraft.world.level.ChunkPos)

Example 9 with BlockGetter

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);
}
Also used : BlockGetter(net.minecraft.world.level.BlockGetter) BlockPos(net.minecraft.core.BlockPos)

Example 10 with BlockGetter

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;
                }
            }
        }
    }
}
Also used : BlockGetter(net.minecraft.world.level.BlockGetter) BlockState(net.minecraft.world.level.block.state.BlockState) ExtendedAbstractBlockState(ca.spottedleaf.starlight.common.blockstate.ExtendedAbstractBlockState) VoxelShape(net.minecraft.world.phys.shapes.VoxelShape) ExtendedAbstractBlockState(ca.spottedleaf.starlight.common.blockstate.ExtendedAbstractBlockState)

Aggregations

BlockGetter (net.minecraft.world.level.BlockGetter)14 BlockPos (net.minecraft.core.BlockPos)8 Level (net.minecraft.world.level.Level)4 ServerLevel (net.minecraft.server.level.ServerLevel)3 BlockState (net.minecraft.world.level.block.state.BlockState)3 VoxelShape (net.minecraft.world.phys.shapes.VoxelShape)3 ExtendedAbstractBlockState (ca.spottedleaf.starlight.common.blockstate.ExtendedAbstractBlockState)2 ServerPlayer (net.minecraft.server.level.ServerPlayer)2 Player (net.minecraft.world.entity.player.Player)2 ChunkPos (net.minecraft.world.level.ChunkPos)2 AllBlocks (com.simibubi.create.AllBlocks)1 AllShapes (com.simibubi.create.AllShapes)1 AllTileEntities (com.simibubi.create.AllTileEntities)1 ITE (com.simibubi.create.foundation.block.ITE)1 BlockHelper (com.simibubi.create.foundation.utility.BlockHelper)1 ArrayList (java.util.ArrayList)1 Optional (java.util.Optional)1 Direction (net.minecraft.core.Direction)1 NonNullList (net.minecraft.core.NonNullList)1 CompoundTag (net.minecraft.nbt.CompoundTag)1