Baritone AI pathfinder

Baritone AI pathfinder

72.7k Downloads

BlockState by BlockPos in Baritone Cache

Nekiplay opened this issue ยท 11 comments

commented

What do you need help with?

How to get BlockState which is hashed by baritone through API by BlockPos in Fabric 1.20.1?

Final checklist

  • I know how to properly use check boxes
  • I have not used any OwO's or UwU's in this issue.
commented

Can you maybe explain what is still missing?

It doesn't get BlockState from the cache, only in the zone of server chunks loading

commented

not sure if this is the best way but basically you want to get the world and on that you can call getBlockState(BlockPos), unless i misunderstood you.

BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world().getBlockState();
commented
BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world().getBlockState();

This does not work if the chunk is not loaded within the loading server radius
I understand the need

BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().worldData().getCachedWorld()

But I don't know how to call getRegion and ICachedRegion getBlock correctly.

commented

something i found but im not sure you can call it as it isnt part of the API i think but it might help you understand how to use the getRegion() and getBlock() methods.

public IBlockState get0(int x, int y, int z) { // Mickey resigned
// Invalid vertical position
if (y < 0 || y >= 256) {
return AIR;
}
if (useTheRealWorld) {
Chunk cached = prev;
// there's great cache locality in block state lookups
// generally it's within each movement
// if it's the same chunk as last time
// we can just skip the mc.world.getChunk lookup
// which is a Long2ObjectOpenHashMap.get
// see issue #113
if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) {
return cached.getBlockState(x, y, z);
}
Chunk chunk = loadedChunks.get(ChunkPos.asLong(x >> 4, z >> 4));
if (chunk != null && chunk.isLoaded()) {
prev = chunk;
return chunk.getBlockState(x, y, z);
}
}
// same idea here, skip the Long2ObjectOpenHashMap.get if at all possible
// except here, it's 512x512 tiles instead of 16x16, so even better repetition
CachedRegion cached = prevCached;
if (cached == null || cached.getX() != x >> 9 || cached.getZ() != z >> 9) {
if (worldData == null) {
return AIR;
}
CachedRegion region = worldData.cache.getRegion(x >> 9, z >> 9);
if (region == null) {
return AIR;
}
prevCached = region;
cached = region;
}
IBlockState type = cached.getBlock(x & 511, y, z & 511);
if (type == null) {
return AIR;
}
return type;
}

commented

something i found but im not sure you can call it as it isnt part of the API i think but it might help you understand how to use the getRegion() and getBlock() methods. https://github.com/cabaletta/baritone/blob/139fd03470116b17b7d07e0a6fc00b640552dcbd/src/main/java/baritone/utils/BlockStateInterface.java#L97C3-L141

java.lang.NoSuchMethodError: 'net.minecraft.class_2248 baritone.utils.BlockStateInterface.getBlock(baritone.api.utils.IPlayerContext, net.minecraft.class_2338)'

Block block = BlockStateInterface.getBlock(BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext(), new BlockPos(rightClickX, rightClickY, rightClickZ));
commented

I made a class with a helper method that uses the bariton cache class, it also returns only loaded player chunks

public static BlockState getBlock(BlockPos pos) {
		World world = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world();
		IWorldData worldData = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().worldData();
		int y = world.getDimension().minY();
		ICachedRegion region = worldData.getCachedWorld().getRegion(pos.getX() >> 9, pos.getZ() >> 9);
		if (region == null) {
			return AIR.getDefaultState();
		}
		else {
			BlockState state = region.getBlock(pos.getX() & 511, pos.getY(), pos.getZ() & 511);
			return state;
		}
	}
commented

Its not completed

commented

Can you maybe explain what is still missing?

commented

You can ignore the "as completed" part. That's just a text github puts there with the only alternative being "not planned".

commented

No example code? or help

commented

Your code does get the state from any loaded cache region and while the area of loaded cache regions can stretch far beyond your render distance it tends to stay close to it. If you want to fetch from arbitrary cached chunks you'll need to make sure they are loaded using CachedWorld.tryLoadFromDist (not part of API but you won't get around non-API methods if you want to retrieve blocks from cache).

Note that most blocks are cached in a simplified forat to save disk space so with few exceptions blocks will be either stone/nethterrack/endstone, air, water or lava when retrieved from cache.