Search in sources :

Example 1 with ChunkSection

use of net.minecraft.world.chunk.ChunkSection in project roadrunner by MaxNeedsSnacks.

the class LandPathNodeMakerMixin method getNodeTypeFromNeighbors.

/**
 * @reason Use optimized implementation which avoids scanning blocks for dangers where possible
 * @author JellySquid
 */
@Overwrite
public static PathNodeType getNodeTypeFromNeighbors(BlockView world, BlockPos.Mutable pos, PathNodeType type) {
    int x = pos.getX();
    int y = pos.getY();
    int z = pos.getZ();
    ChunkSection section = null;
    // reads to just one chunk and avoid hits against the server chunk manager.
    if (world instanceof CollisionView && WorldHelper.areNeighborsWithinSameChunk(pos)) {
        // if the cached chunk section was initialized will early-exit.
        if (!World.isOutOfBuildLimitVertically(y)) {
            // This cast is always safe and is necessary to obtain direct references to chunk sections.
            Chunk chunk = (Chunk) ((CollisionView) world).getExistingChunk(x >> 4, z >> 4);
            // An empty chunk or section will never pose any danger sources, which will be caught later.
            if (chunk != null) {
                section = chunk.getSectionArray()[y >> 4];
            }
        }
        // against this chunk section will always fail, allowing us to fast-exit.
        if (ChunkSection.isEmpty(section) || PathNodeCache.isSectionSafeAsNeighbor(section)) {
            return type;
        }
    }
    int xStart = x - 1;
    int yStart = y - 1;
    int zStart = z - 1;
    int xEnd = x + 1;
    int yEnd = y + 1;
    int zEnd = z + 1;
    // Vanilla iteration order is XYZ
    for (int adjX = xStart; adjX <= xEnd; adjX++) {
        for (int adjY = yStart; adjY <= yEnd; adjY++) {
            for (int adjZ = zStart; adjZ <= zEnd; adjZ++) {
                // Skip the vertical column of the origin block
                if (adjX == x && adjZ == z) {
                    continue;
                }
                BlockState state;
                // retrieval by calling upon the cached chunk directly.
                if (section != null) {
                    state = section.getBlockState(adjX & 15, adjY & 15, adjZ & 15);
                } else {
                    state = world.getBlockState(pos.set(adjX, adjY, adjZ));
                }
                // Ensure that the block isn't air first to avoid expensive hash table accesses
                if (state.isAir()) {
                    continue;
                }
                PathNodeType neighborType = PathNodeCache.getNeighborPathNodeType(state);
                if (neighborType != PathNodeType.OPEN) {
                    return neighborType;
                }
            }
        }
    }
    return type;
}
Also used : BlockState(net.minecraft.block.BlockState) CollisionView(net.minecraft.world.CollisionView) PathNodeType(net.minecraft.entity.ai.pathing.PathNodeType) Chunk(net.minecraft.world.chunk.Chunk) ChunkSection(net.minecraft.world.chunk.ChunkSection) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 2 with ChunkSection

use of net.minecraft.world.chunk.ChunkSection in project roadrunner by MaxNeedsSnacks.

the class ExplosionMixin method traverseBlock.

/**
 * Called for every step made by a ray being cast by an explosion.
 *
 * @param strength The strength of the ray during this step
 * @param blockX   The x-coordinate of the block the ray is inside of
 * @param blockY   The y-coordinate of the block the ray is inside of
 * @param blockZ   The z-coordinate of the block the ray is inside of
 * @return The resistance of the current block space to the ray
 */
private float traverseBlock(float strength, int blockX, int blockY, int blockZ, LongOpenHashSet touched) {
    BlockPos pos = this.cachedPos.set(blockX, blockY, blockZ);
    // Early-exit if the y-coordinate is out of bounds.
    if (World.isOutOfBuildLimitVertically(blockY)) {
        Optional<Float> blastResistance = this.behavior.getBlastResistance((Explosion) (Object) this, this.world, pos, Blocks.AIR.getDefaultState(), Fluids.EMPTY.getDefaultState());
        // noinspection OptionalIsPresent
        if (blastResistance.isPresent()) {
            return (blastResistance.get() + 0.3F) * 0.3F;
        }
        return 0.0F;
    }
    int chunkX = blockX >> 4;
    int chunkZ = blockZ >> 4;
    // Avoid calling into the chunk manager as much as possible through managing chunks locally
    if (this.prevChunkX != chunkX || this.prevChunkZ != chunkZ) {
        this.prevChunk = this.world.getChunk(chunkX, chunkZ);
        this.prevChunkX = chunkX;
        this.prevChunkZ = chunkZ;
    }
    final Chunk chunk = this.prevChunk;
    BlockState blockState = Blocks.AIR.getDefaultState();
    float totalResistance = 0.0F;
    Optional<Float> blastResistance;
    labelGetBlastResistance: {
        // If the chunk is missing or out of bounds, assume that it is air
        if (chunk != null) {
            // We operate directly on chunk sections to avoid interacting with BlockPos and to squeeze out as much
            // performance as possible here
            ChunkSection section = chunk.getSectionArray()[blockY >> 4];
            // If the section doesn't exist or it's empty, assume that the block is air
            if (section != null && !section.isEmpty()) {
                // Retrieve the block state from the chunk section directly to avoid associated overhead
                blockState = section.getBlockState(blockX & 15, blockY & 15, blockZ & 15);
                // If the block state is air, it cannot have fluid or any kind of resistance, so just leave
                if (blockState.getBlock() != Blocks.AIR) {
                    // Rather than query the fluid state from the container as we just did with the block state, we can
                    // simply ask the block state we retrieved what fluid it has. This is exactly what the call would
                    // do anyways, except that it would have to retrieve the block state a second time, adding overhead.
                    FluidState fluidState = blockState.getFluidState();
                    // Get the explosion resistance like vanilla
                    blastResistance = this.behavior.getBlastResistance((Explosion) (Object) this, this.world, pos, blockState, fluidState);
                    break labelGetBlastResistance;
                }
            }
        }
        blastResistance = this.behavior.getBlastResistance((Explosion) (Object) this, this.world, pos, Blocks.AIR.getDefaultState(), Fluids.EMPTY.getDefaultState());
    }
    // Calculate how much this block will resist an explosion's ray
    if (blastResistance.isPresent()) {
        totalResistance = (blastResistance.get() + 0.3F) * 0.3F;
    }
    // Check if this ray is still strong enough to break blocks, and if so, add this position to the set
    // of positions to destroy
    float reducedStrength = strength - totalResistance;
    if (reducedStrength > 0.0F && (this.explodeAirBlocks || !blockState.isAir())) {
        if (this.behavior.canDestroyBlock((Explosion) (Object) this, this.world, pos, blockState, reducedStrength)) {
            touched.add(pos.asLong());
        }
    }
    return totalResistance;
}
Also used : BlockState(net.minecraft.block.BlockState) Explosion(net.minecraft.world.explosion.Explosion) BlockPos(net.minecraft.util.math.BlockPos) Chunk(net.minecraft.world.chunk.Chunk) ChunkSection(net.minecraft.world.chunk.ChunkSection) FluidState(net.minecraft.fluid.FluidState)

Example 3 with ChunkSection

use of net.minecraft.world.chunk.ChunkSection in project polymer-core by teampolymer.

the class VirtualChunk method setBlockState.

@Override
public BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving) {
    int x = pos.getX() & 15;
    int y = pos.getY();
    int z = pos.getZ() & 15;
    ChunkSection chunksection = this.getSections()[y >> 4];
    if (chunksection == EMPTY_SECTION) {
        if (state.isAir()) {
            return null;
        }
        chunksection = new ChunkSection(y >> 4 << 4);
        this.getSections()[y >> 4] = chunksection;
    }
    if (!state.isAir()) {
        this.isEmpty = false;
    }
    BlockState oldState = chunksection.setBlockState(x, y & 15, z, state);
    if (oldState == state) {
        return null;
    } else {
        Block newBlock = state.getBlock();
        Block oldBlock = oldState.getBlock();
        this.getOrCreateHeightmapUnprimed(Heightmap.Type.MOTION_BLOCKING).update(x, y, z, state);
        this.getOrCreateHeightmapUnprimed(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES).update(x, y, z, state);
        this.getOrCreateHeightmapUnprimed(Heightmap.Type.OCEAN_FLOOR).update(x, y, z, state);
        this.getOrCreateHeightmapUnprimed(Heightmap.Type.WORLD_SURFACE).update(x, y, z, state);
        if ((oldBlock != newBlock || !state.hasTileEntity()) && oldState.hasTileEntity()) {
        // this.world.removeTileEntity(pos);
        }
        if (!chunksection.getBlockState(x, y & 15, z).is(newBlock)) {
            return null;
        } else {
            if (oldState.hasTileEntity()) {
                TileEntity tileentity = this.getBlockEntity(pos, Chunk.CreateEntityType.CHECK);
                if (tileentity != null) {
                    tileentity.clearCache();
                }
            }
            if (state.hasTileEntity()) {
                TileEntity te = this.getBlockEntity(pos, Chunk.CreateEntityType.CHECK);
                if (te == null) {
                    te = state.createTileEntity(this.getLevel());
                // this.world.setTileEntity(pos, te);
                } else {
                    te.clearCache();
                }
            }
            this.markUnsaved();
            return oldState;
        }
    }
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) BlockState(net.minecraft.block.BlockState) Block(net.minecraft.block.Block) ChunkSection(net.minecraft.world.chunk.ChunkSection)

Example 4 with ChunkSection

use of net.minecraft.world.chunk.ChunkSection in project polymer-core by teampolymer.

the class VirtualChunk method getBlockState.

@Override
@NotNull
public BlockState getBlockState(BlockPos pos) {
    int x = pos.getX() & 0xF;
    int y = pos.getY();
    int z = pos.getZ() & 0xF;
    int cy = y >> 4;
    ChunkSection[] sections = this.getSections();
    if (cy >= 0 && cy < sections.length) {
        ChunkSection chunkSection = sections[cy];
        if (!ChunkSection.isEmpty(chunkSection)) {
            return chunkSection.getBlockState(x, y & 0xF, z);
        }
    }
    return AIR;
}
Also used : ChunkSection(net.minecraft.world.chunk.ChunkSection) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with ChunkSection

use of net.minecraft.world.chunk.ChunkSection in project lithium-fabric by CaffeineMC.

the class ChunkCacheMixin method getBlockState.

/**
 * @reason Use optimized function
 * @author JellySquid
 */
@Overwrite
public BlockState getBlockState(BlockPos pos) {
    int y = pos.getY();
    if (!(y < this.bottomY || y >= this.topY)) {
        int x = pos.getX();
        int z = pos.getZ();
        int chunkX = (Pos.ChunkCoord.fromBlockCoord(x)) - this.minX;
        int chunkZ = (Pos.ChunkCoord.fromBlockCoord(z)) - this.minZ;
        if (chunkX >= 0 && chunkX < this.xLen && chunkZ >= 0 && chunkZ < this.zLen) {
            Chunk chunk = this.chunksFlat[(chunkX * this.zLen) + chunkZ];
            // Avoid going through Chunk#getBlockState
            if (chunk != null) {
                ChunkSection section = chunk.getSectionArray()[Pos.SectionYIndex.fromBlockCoord(this, y)];
                if (section != null) {
                    return section.getBlockState(x & 15, y & 15, z & 15);
                }
            }
        }
    }
    return DEFAULT_BLOCK;
}
Also used : Chunk(net.minecraft.world.chunk.Chunk) ChunkSection(net.minecraft.world.chunk.ChunkSection) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Aggregations

ChunkSection (net.minecraft.world.chunk.ChunkSection)21 Chunk (net.minecraft.world.chunk.Chunk)11 BlockState (net.minecraft.block.BlockState)9 Overwrite (org.spongepowered.asm.mixin.Overwrite)8 BlockPos (net.minecraft.util.math.BlockPos)3 WorldChunk (net.minecraft.world.chunk.WorldChunk)3 PathNodeType (net.minecraft.entity.ai.pathing.PathNodeType)2 FluidState (net.minecraft.fluid.FluidState)2 CollisionView (net.minecraft.world.CollisionView)2 IChunk (net.minecraft.world.chunk.IChunk)2 Explosion (net.minecraft.world.explosion.Explosion)2 Inject (org.spongepowered.asm.mixin.injection.Inject)2 BlockCountingSection (me.jellysquid.mods.lithium.common.block.BlockCountingSection)1 TrackedBlockStatePredicate (me.jellysquid.mods.lithium.common.block.TrackedBlockStatePredicate)1 Block (net.minecraft.block.Block)1 ChunkOcclusionDataBuilder (net.minecraft.client.render.chunk.ChunkOcclusionDataBuilder)1 TileEntity (net.minecraft.tileentity.TileEntity)1 NotNull (org.jetbrains.annotations.NotNull)1 IDungeonPart (team.cqr.cqrepoured.world.structure.generation.generation.part.IDungeonPart)1