Cached Chunk Path Finding

This commit is contained in:
Brady 2018-08-07 19:41:13 -05:00
parent b5ddd17131
commit 3f7b552577
No known key found for this signature in database
GPG Key ID: 73A788379A197567
7 changed files with 122 additions and 12 deletions

View File

@ -1,10 +1,20 @@
package baritone.bot; package baritone.bot;
import baritone.bot.behavior.Behavior; import baritone.bot.behavior.Behavior;
import baritone.bot.chunk.CachedWorld;
import baritone.bot.chunk.CachedWorldProvider;
import baritone.bot.chunk.ChunkPacker;
import baritone.bot.event.IGameEventListener; import baritone.bot.event.IGameEventListener;
import baritone.bot.event.events.*; import baritone.bot.event.events.*;
import baritone.bot.event.events.type.EventState;
import baritone.bot.utils.Helper;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.settings.KeyBinding; import net.minecraft.client.settings.KeyBinding;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -12,7 +22,7 @@ import java.util.function.Consumer;
* @author Brady * @author Brady
* @since 7/31/2018 11:04 PM * @since 7/31/2018 11:04 PM
*/ */
public final class GameEventHandler implements IGameEventListener { public final class GameEventHandler implements IGameEventListener, Helper {
GameEventHandler() {} GameEventHandler() {}
@ -52,8 +62,6 @@ public final class GameEventHandler implements IGameEventListener {
@Override @Override
public void onChunkEvent(ChunkEvent event) { public void onChunkEvent(ChunkEvent event) {
/*
EventState state = event.getState(); EventState state = event.getState();
ChunkEvent.Type type = event.getType(); ChunkEvent.Type type = event.getType();
@ -72,19 +80,23 @@ public final class GameEventHandler implements IGameEventListener {
world.updateCachedChunk(event.getX(), event.getZ(), world.updateCachedChunk(event.getX(), event.getZ(),
ChunkPacker.createPackedChunk(mc.world.getChunk(event.getX(), event.getZ())))); ChunkPacker.createPackedChunk(mc.world.getChunk(event.getX(), event.getZ()))));
} }
*/
dispatch(behavior -> behavior.onChunkEvent(event)); dispatch(behavior -> behavior.onChunkEvent(event));
} }
@Override @Override
public void onRenderPass(RenderEvent event) { public void onRenderPass(RenderEvent event) {
/*
CachedWorldProvider.INSTANCE.ifWorldLoaded(world -> world.forEachRegion(region -> region.forEachChunk(chunk -> {
drawChunkLine(region.getX() * 512 + chunk.getX() * 16, region.getZ() * 512 + chunk.getZ() * 16, event.getPartialTicks());
})));
*/
dispatch(behavior -> behavior.onRenderPass(event)); dispatch(behavior -> behavior.onRenderPass(event));
} }
@Override @Override
public void onWorldEvent(WorldEvent event) { public void onWorldEvent(WorldEvent event) {
/*
CachedWorldProvider cache = CachedWorldProvider.INSTANCE; CachedWorldProvider cache = CachedWorldProvider.INSTANCE;
switch (event.getState()) { switch (event.getState()) {
@ -97,7 +109,6 @@ public final class GameEventHandler implements IGameEventListener {
cache.initWorld(event.getWorld()); cache.initWorld(event.getWorld());
break; break;
} }
*/
dispatch(behavior -> behavior.onWorldEvent(event)); dispatch(behavior -> behavior.onWorldEvent(event));
} }
@ -115,4 +126,27 @@ public final class GameEventHandler implements IGameEventListener {
private void dispatch(Consumer<Behavior> dispatchFunction) { private void dispatch(Consumer<Behavior> dispatchFunction) {
Baritone.INSTANCE.getBehaviors().stream().filter(Behavior::isEnabled).forEach(dispatchFunction); Baritone.INSTANCE.getBehaviors().stream().filter(Behavior::isEnabled).forEach(dispatchFunction);
} }
private void drawChunkLine(int posX, int posZ, float partialTicks) {
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GlStateManager.color(1.0F, 1.0F, 0.0F, 0.4F);
GL11.glLineWidth(2.0F);
GlStateManager.disableTexture2D();
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
double d0 = mc.getRenderManager().viewerPosX;
double d1 = mc.getRenderManager().viewerPosY;
double d2 = mc.getRenderManager().viewerPosZ;
buffer.begin(3, DefaultVertexFormats.POSITION);
buffer.pos(posX - d0, 0 - d1, posZ - d2).endVertex();
buffer.pos(posX - d0, 256 - d1, posZ - d2).endVertex();
tessellator.draw();
GlStateManager.enableDepth();
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
}
} }

View File

@ -11,6 +11,7 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Arrays; import java.util.Arrays;
import java.util.BitSet; import java.util.BitSet;
import java.util.function.Consumer;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
/** /**
@ -62,6 +63,17 @@ public final class CachedRegion implements ICachedChunkAccess {
return this.chunks[chunkX][chunkZ]; return this.chunks[chunkX][chunkZ];
} }
public void forEachChunk(Consumer<CachedChunk> consumer) {
for (int x = 0; x < 32; x++) {
for (int z = 0; z < 32; z++) {
CachedChunk chunk = getChunk(x, z);
if (chunk != null) {
consumer.accept(chunk);
}
}
}
}
public final void save(String directory) { public final void save(String directory) {
try { try {
Path path = Paths.get(directory); Path path = Paths.get(directory);

View File

@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.BitSet; import java.util.BitSet;
import java.util.function.Consumer;
/** /**
* @author Brady * @author Brady
@ -83,7 +84,7 @@ public final class CachedWorld implements ICachedChunkAccess {
* @param regionZ The region Z coordinate * @param regionZ The region Z coordinate
* @return The region located at the specified coordinates * @return The region located at the specified coordinates
*/ */
private CachedRegion getOrCreateRegion(int regionX, int regionZ) { CachedRegion getOrCreateRegion(int regionX, int regionZ) {
return cachedRegions.computeIfAbsent(getRegionID(regionX, regionZ), id -> { return cachedRegions.computeIfAbsent(getRegionID(regionX, regionZ), id -> {
CachedRegion newRegion = new CachedRegion(regionX, regionZ); CachedRegion newRegion = new CachedRegion(regionX, regionZ);
newRegion.load(this.directory); newRegion.load(this.directory);
@ -91,6 +92,13 @@ public final class CachedWorld implements ICachedChunkAccess {
}); });
} }
public void forEachRegion(Consumer<CachedRegion> consumer) {
this.cachedRegions.forEach((id, r) -> {
if (r != null)
consumer.accept(r);
});
}
/** /**
* Returns the region ID based on the region coordinates. 0 will be * Returns the region ID based on the region coordinates. 0 will be
* returned if the specified region coordinates are out of bounds. * returned if the specified region coordinates are out of bounds.

View File

@ -14,6 +14,8 @@ import java.nio.file.Path;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* @author Brady * @author Brady
@ -23,6 +25,8 @@ public enum CachedWorldProvider implements Helper {
INSTANCE; INSTANCE;
private static final Pattern REGION_REGEX = Pattern.compile("r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.bcr");
private final Map<String, CachedWorld> singlePlayerWorldCache = new HashMap<>(); private final Map<String, CachedWorld> singlePlayerWorldCache = new HashMap<>();
private CachedWorld currentWorld; private CachedWorld currentWorld;
@ -47,6 +51,20 @@ public enum CachedWorldProvider implements Helper {
} }
this.currentWorld = this.singlePlayerWorldCache.computeIfAbsent(dir.toString(), CachedWorld::new); this.currentWorld = this.singlePlayerWorldCache.computeIfAbsent(dir.toString(), CachedWorld::new);
try {
Files.list(dir).forEach(path -> {
String file = path.getFileName().toString();
Matcher matcher = REGION_REGEX.matcher(file);
if (matcher.matches()) {
int rx = Integer.parseInt(matcher.group(1));
int ry = Integer.parseInt(matcher.group(2));
// Recognize the region for when we load from file
this.currentWorld.getOrCreateRegion(rx, ry);
}
});
} catch (Exception ignored) {}
this.currentWorld.load(); this.currentWorld.load();
} }
// TODO: Store server worlds // TODO: Store server worlds

View File

@ -1,5 +1,6 @@
package baritone.bot.pathing.calc; package baritone.bot.pathing.calc;
import baritone.bot.chunk.CachedWorldProvider;
import baritone.bot.pathing.calc.openset.BinaryHeapOpenSet; import baritone.bot.pathing.calc.openset.BinaryHeapOpenSet;
import baritone.bot.pathing.calc.openset.IOpenSet; import baritone.bot.pathing.calc.openset.IOpenSet;
import baritone.bot.pathing.goals.Goal; import baritone.bot.pathing.goals.Goal;
@ -83,7 +84,13 @@ public class AStarPathFinder extends AbstractNodeCostSearch {
if (movementToGetToNeighbor == null) { if (movementToGetToNeighbor == null) {
continue; continue;
} }
if (Minecraft.getMinecraft().world.getChunk(movementToGetToNeighbor.getDest()) instanceof EmptyChunk) {
boolean isPositionCached = false;
if (CachedWorldProvider.INSTANCE.getCurrentWorld() != null)
if (CachedWorldProvider.INSTANCE.getCurrentWorld().getBlockType(movementToGetToNeighbor.getDest()) != null)
isPositionCached = true;
if (Minecraft.getMinecraft().world.getChunk(movementToGetToNeighbor.getDest()) instanceof EmptyChunk && !isPositionCached) {
numEmptyChunk++; numEmptyChunk++;
continue; continue;
} }

View File

@ -1,16 +1,47 @@
package baritone.bot.utils; package baritone.bot.utils;
import baritone.bot.chunk.CachedWorld;
import baritone.bot.chunk.CachedWorldProvider;
import baritone.bot.pathing.util.PathingBlockType;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockFalling; import net.minecraft.block.BlockFalling;
import net.minecraft.block.BlockLiquid; import net.minecraft.block.BlockLiquid;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.Chunk;
public class BlockStateInterface implements Helper {
public class BlockStateInterface {
public static IBlockState get(BlockPos pos) { // wrappers for future chunk caching capability public static IBlockState get(BlockPos pos) { // wrappers for future chunk caching capability
return Minecraft.getMinecraft().world.getBlockState(pos);
// Invalid vertical position
if (pos.getY() < 0 || pos.getY() >= 256)
return Blocks.AIR.getDefaultState();
Chunk chunk = mc.world.getChunk(pos);
if (chunk.isLoaded()) {
return chunk.getBlockState(pos);
} else {
CachedWorld world = CachedWorldProvider.INSTANCE.getCurrentWorld();
if (world != null) {
PathingBlockType type = world.getBlockType(pos);
if (type != null) {
switch (type) {
case AIR:
return Blocks.AIR.getDefaultState();
case WATER:
return Blocks.WATER.getDefaultState();
case AVOID:
return Blocks.LAVA.getDefaultState();
case SOLID:
return Blocks.OBSIDIAN.getDefaultState();
}
}
}
}
return Blocks.AIR.getDefaultState();
} }
public static Block getBlock(BlockPos pos) { public static Block getBlock(BlockPos pos) {

View File

@ -4,7 +4,7 @@ import net.minecraft.util.Tuple;
public class Rotation extends Tuple<Float, Float> { public class Rotation extends Tuple<Float, Float> {
public Rotation(Float yaw, Float pitch) { public Rotation(float yaw, float pitch) {
super(yaw, pitch); super(yaw, pitch);
} }
} }