Search in sources :

Example 1 with PathNodeType

use of net.minecraft.entity.ai.pathing.PathNodeType 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 PathNodeType

use of net.minecraft.entity.ai.pathing.PathNodeType in project lithium-fabric by CaffeineMC.

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.isOutOfHeightLimit(y)) {
            // This cast is always safe and is necessary to obtain direct references to chunk sections.
            Chunk chunk = (Chunk) ((CollisionView) world).getChunkAsView(Pos.ChunkCoord.fromBlockCoord(x), Pos.ChunkCoord.fromBlockCoord(z));
            // An empty chunk or section will never pose any danger sources, which will be caught later.
            if (chunk != null) {
                section = chunk.getSectionArray()[Pos.SectionYIndex.fromBlockCoord(world, y)];
            }
        }
        // against this chunk section will always fail, allowing us to fast-exit.
        if (section == null || 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 3 with PathNodeType

use of net.minecraft.entity.ai.pathing.PathNodeType in project roadrunner by MaxNeedsSnacks.

the class LandPathNodeMakerMixin method getCommonNodeType.

/**
 * @reason Use optimized implementation
 * @author JellySquid
 */
@Overwrite
public static PathNodeType getCommonNodeType(BlockView blockView, BlockPos blockPos) {
    BlockState blockState = blockView.getBlockState(blockPos);
    PathNodeType type;
    if (((DetailedBlockPathingBehavior) blockState.getBlock()).needsDynamicNodeTypeCheck()) {
        type = blockState.getAiPathNodeType(blockView, blockPos);
        if (type == null) {
            type = PathNodeCache.getPathNodeType(blockState);
        }
    } else {
        type = PathNodeCache.getPathNodeType(blockState);
        if (type != PathNodeType.LAVA && type != PathNodeType.DANGER_FIRE && ((DetailedBlockPathingBehavior) blockState.getBlock()).needsDynamicBurningCheck() && blockState.isBurning(blockView, blockPos)) {
            type = PathNodeType.DANGER_FIRE;
        }
    }
    // to check the fallback path.
    if (type == PathNodeType.OPEN) {
        // since fluids will always pass this check.
        if (!blockState.canPathfindThrough(blockView, blockPos, NavigationType.LAND)) {
            return PathNodeType.BLOCKED;
        }
        // All checks succeed, this path node really is open!
        return PathNodeType.OPEN;
    }
    // Return the cached value since we found an obstacle earlier
    return type;
}
Also used : BlockState(net.minecraft.block.BlockState) DetailedBlockPathingBehavior(me.jellysquid.mods.lithium.common.ai.pathing.DetailedBlockPathingBehavior) PathNodeType(net.minecraft.entity.ai.pathing.PathNodeType) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 4 with PathNodeType

use of net.minecraft.entity.ai.pathing.PathNodeType in project lithium-fabric by CaffeineMC.

the class LandPathNodeMakerMixin method getCommonNodeType.

/**
 * @reason Use optimized implementation
 * @author JellySquid
 */
@Overwrite
public static PathNodeType getCommonNodeType(BlockView blockView, BlockPos blockPos) {
    BlockState blockState = blockView.getBlockState(blockPos);
    PathNodeType type = PathNodeCache.getPathNodeType(blockState);
    // to check the fallback path.
    if (type == PathNodeType.OPEN || type == PathNodeType.WATER) {
        // since fluids will always pass this check.
        if (!blockState.canPathfindThrough(blockView, blockPos, NavigationType.LAND)) {
            return PathNodeType.BLOCKED;
        }
        // All checks succeed, this path node really is open!
        return type;
    }
    // Return the cached value since we found an obstacle earlier
    return type;
}
Also used : BlockState(net.minecraft.block.BlockState) PathNodeType(net.minecraft.entity.ai.pathing.PathNodeType) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Aggregations

BlockState (net.minecraft.block.BlockState)4 PathNodeType (net.minecraft.entity.ai.pathing.PathNodeType)4 Overwrite (org.spongepowered.asm.mixin.Overwrite)4 CollisionView (net.minecraft.world.CollisionView)2 Chunk (net.minecraft.world.chunk.Chunk)2 ChunkSection (net.minecraft.world.chunk.ChunkSection)2 DetailedBlockPathingBehavior (me.jellysquid.mods.lithium.common.ai.pathing.DetailedBlockPathingBehavior)1