Cached Chunk Path Finding
This commit is contained in:
parent
b5ddd17131
commit
3f7b552577
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user