Add individual chunk scanning to IWorldScanner

This commit is contained in:
Brady 2018-12-14 18:50:39 -06:00
parent d4947c3c47
commit 2afdaa1ac9
No known key found for this signature in database
GPG Key ID: 73A788379A197567
2 changed files with 58 additions and 0 deletions

View File

@ -20,6 +20,7 @@ package baritone.api.cache;
import baritone.api.utils.IPlayerContext;
import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import java.util.List;
@ -42,4 +43,18 @@ public interface IWorldScanner {
* @return The matching block positions
*/
List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
/**
* Scans a single chunk for the specified blocks.
*
* @param ctx The {@link IPlayerContext} containing player and world info that the
* scan is based upon
* @param blocks The blocks to scan for
* @param pos The position of the target chunk
* @param max The maximum number of blocks to scan before cutoff
* @param yLevelThreshold If a block is found within this Y level, the current result will be
* returned, if the value is negative, then this condition doesn't apply.
* @return The matching block positions
*/
List<BlockPos> scanChunk(IPlayerContext ctx, List<Block> blocks, ChunkPos pos, int max, int yLevelThreshold);
}

View File

@ -23,10 +23,12 @@ import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.multiplayer.ChunkProviderClient;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.chunk.BlockStateContainer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@ -107,4 +109,45 @@ public enum WorldScanner implements IWorldScanner {
searchRadiusSq++;
}
}
@Override
public List<BlockPos> scanChunk(IPlayerContext ctx, List<Block> blocks, ChunkPos pos, int max, int yLevelThreshold) {
if (blocks.isEmpty()) {
return Collections.emptyList();
}
ChunkProviderClient chunkProvider = (ChunkProviderClient) ctx.world().getChunkProvider();
Chunk chunk = chunkProvider.getLoadedChunk(pos.x, pos.z);
int playerY = ctx.playerFeet().getY();
if (chunk == null || chunk.isEmpty()) {
return Collections.emptyList();
}
LinkedList<BlockPos> res = new LinkedList<>();
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
for (int y0 = 0; y0 < 16; y0++) {
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
if (extendedblockstorage == null) {
continue;
}
int yReal = y0 << 4;
BlockStateContainer bsc = extendedblockstorage.getData();
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
IBlockState state = bsc.get(x, y, z);
if (blocks.contains(state.getBlock())) {
int yy = yReal | y;
res.add(new BlockPos((pos.x << 4) | x, yy, (pos.z << 4) | z));
if (res.size() >= max || Math.abs(yy - playerY) < yLevelThreshold) {
return res;
}
}
}
}
}
}
return res;
}
}