> getBlocks() {
+ return this.blocks;
+ }
+}
diff --git a/src/api/java/baritone/api/event/events/ChunkEvent.java b/src/api/java/baritone/api/event/events/ChunkEvent.java
index a7b5d96f0..bb22a47b1 100644
--- a/src/api/java/baritone/api/event/events/ChunkEvent.java
+++ b/src/api/java/baritone/api/event/events/ChunkEvent.java
@@ -57,31 +57,38 @@ public final class ChunkEvent {
/**
* @return The state of the event
*/
- public final EventState getState() {
+ public EventState getState() {
return this.state;
}
/**
* @return The type of chunk event that occurred;
*/
- public final Type getType() {
+ public Type getType() {
return this.type;
}
/**
* @return The Chunk X position.
*/
- public final int getX() {
+ public int getX() {
return this.x;
}
/**
* @return The Chunk Z position.
*/
- public final int getZ() {
+ public int getZ() {
return this.z;
}
+ /**
+ * @return {@code true} if the event was fired after a chunk population
+ */
+ public boolean isPostPopulate() {
+ return this.state == EventState.POST && this.type.isPopulate();
+ }
+
public enum Type {
/**
diff --git a/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java b/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java
index 9eac8de46..64ae0c16e 100644
--- a/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java
+++ b/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java
@@ -45,6 +45,9 @@ public interface AbstractGameEventListener extends IGameEventListener {
@Override
default void onChunkEvent(ChunkEvent event) {}
+ @Override
+ default void onBlockChange(BlockChangeEvent event) {}
+
@Override
default void onRenderPass(RenderEvent event) {}
diff --git a/src/api/java/baritone/api/event/listener/IGameEventListener.java b/src/api/java/baritone/api/event/listener/IGameEventListener.java
index b074e978b..71e9521ad 100644
--- a/src/api/java/baritone/api/event/listener/IGameEventListener.java
+++ b/src/api/java/baritone/api/event/listener/IGameEventListener.java
@@ -72,6 +72,13 @@ public interface IGameEventListener {
*/
void onChunkEvent(ChunkEvent event);
+ /**
+ * Runs after a single or multi block change packet is received and processed.
+ *
+ * @param event The event
+ */
+ void onBlockChange(BlockChangeEvent event);
+
/**
* Runs once per world render pass. Two passes are made when {@link GameSettings#anaglyph} is on.
*
diff --git a/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java b/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java
index f1c1f7972..cdbeffc6c 100644
--- a/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java
+++ b/src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java
@@ -17,24 +17,29 @@
package baritone.launch.mixins;
-import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
+import baritone.api.event.events.BlockChangeEvent;
import baritone.api.event.events.ChunkEvent;
import baritone.api.event.events.type.EventState;
-import baritone.cache.CachedChunk;
-import net.minecraft.client.entity.EntityPlayerSP;
+import baritone.api.utils.Pair;
+import net.minecraft.block.state.IBlockState;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.network.play.server.SPacketBlockChange;
import net.minecraft.network.play.server.SPacketChunkData;
import net.minecraft.network.play.server.SPacketCombatEvent;
import net.minecraft.network.play.server.SPacketMultiBlockChange;
+import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.stream.Collectors;
+
/**
* @author Brady
* @since 8/3/2018
@@ -50,19 +55,18 @@ public class MixinNetHandlerPlayClient {
)
)
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
- for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
- EntityPlayerSP player = ibaritone.getPlayerContext().player();
- if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
- ibaritone.getGameEventHandler().onChunkEvent(
- new ChunkEvent(
- EventState.PRE,
- packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
- packetIn.getChunkX(),
- packetIn.getChunkZ()
- )
- );
- }
+ IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
+ if (baritone == null) {
+ return;
}
+ baritone.getGameEventHandler().onChunkEvent(
+ new ChunkEvent(
+ EventState.PRE,
+ packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
+ packetIn.getChunkX(),
+ packetIn.getChunkZ()
+ )
+ );
}
@Inject(
@@ -70,19 +74,18 @@ public class MixinNetHandlerPlayClient {
at = @At("RETURN")
)
private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
- for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
- EntityPlayerSP player = ibaritone.getPlayerContext().player();
- if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
- ibaritone.getGameEventHandler().onChunkEvent(
- new ChunkEvent(
- EventState.POST,
- packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
- packetIn.getChunkX(),
- packetIn.getChunkZ()
- )
- );
- }
+ IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
+ if (baritone == null) {
+ return;
}
+ baritone.getGameEventHandler().onChunkEvent(
+ new ChunkEvent(
+ EventState.POST,
+ packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
+ packetIn.getChunkX(),
+ packetIn.getChunkZ()
+ )
+ );
}
@Inject(
@@ -90,25 +93,14 @@ public class MixinNetHandlerPlayClient {
at = @At("RETURN")
)
private void postHandleBlockChange(SPacketBlockChange packetIn, CallbackInfo ci) {
- if (!Baritone.settings().repackOnAnyBlockChange.value) {
+ IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
+ if (baritone == null) {
return;
}
- if (!CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(packetIn.getBlockState().getBlock())) {
- return;
- }
- for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
- EntityPlayerSP player = ibaritone.getPlayerContext().player();
- if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
- ibaritone.getGameEventHandler().onChunkEvent(
- new ChunkEvent(
- EventState.POST,
- ChunkEvent.Type.POPULATE_FULL,
- packetIn.getBlockPosition().getX() >> 4,
- packetIn.getBlockPosition().getZ() >> 4
- )
- );
- }
- }
+
+ final ChunkPos pos = new ChunkPos(packetIn.getBlockPosition().getX() >> 4, packetIn.getBlockPosition().getZ() >> 4);
+ final Pair changed = new Pair<>(packetIn.getBlockPosition(), packetIn.getBlockState());
+ baritone.getGameEventHandler().onBlockChange(new BlockChangeEvent(pos, Collections.singletonList(changed)));
}
@Inject(
@@ -116,35 +108,20 @@ public class MixinNetHandlerPlayClient {
at = @At("RETURN")
)
private void postHandleMultiBlockChange(SPacketMultiBlockChange packetIn, CallbackInfo ci) {
- if (!Baritone.settings().repackOnAnyBlockChange.value) {
+ IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
+ if (baritone == null) {
return;
}
- if (packetIn.getChangedBlocks().length == 0) {
- return;
- }
- https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.15
- {
- for (SPacketMultiBlockChange.BlockUpdateData update : packetIn.getChangedBlocks()) {
- if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(update.getBlockState().getBlock())) {
- break https;
- }
- }
- return;
- }
- ChunkPos pos = new ChunkPos(packetIn.getChangedBlocks()[0].getPos());
- for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
- EntityPlayerSP player = ibaritone.getPlayerContext().player();
- if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
- ibaritone.getGameEventHandler().onChunkEvent(
- new ChunkEvent(
- EventState.POST,
- ChunkEvent.Type.POPULATE_FULL,
- pos.x,
- pos.z
- )
- );
- }
- }
+
+ // All blocks have the same ChunkPos
+ final ChunkPos pos = new ChunkPos(packetIn.getChangedBlocks()[0].getPos());
+
+ baritone.getGameEventHandler().onBlockChange(new BlockChangeEvent(
+ pos,
+ Arrays.stream(packetIn.getChangedBlocks())
+ .map(data -> new Pair<>(data.getPos(), data.getBlockState()))
+ .collect(Collectors.toList())
+ ));
}
@Inject(
@@ -155,11 +132,10 @@ public class MixinNetHandlerPlayClient {
)
)
private void onPlayerDeath(SPacketCombatEvent packetIn, CallbackInfo ci) {
- for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
- EntityPlayerSP player = ibaritone.getPlayerContext().player();
- if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
- ibaritone.getGameEventHandler().onPlayerDeath();
- }
+ IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
+ if (baritone == null) {
+ return;
}
+ baritone.getGameEventHandler().onPlayerDeath();
}
}
diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java
index 3da503066..200ca48cb 100644
--- a/src/main/java/baritone/behavior/ElytraBehavior.java
+++ b/src/main/java/baritone/behavior/ElytraBehavior.java
@@ -19,9 +19,9 @@ package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IElytraBehavior;
+import baritone.api.event.events.BlockChangeEvent;
import baritone.api.event.events.ChunkEvent;
import baritone.api.event.events.TickEvent;
-import baritone.api.event.events.type.EventState;
import baritone.api.utils.*;
import baritone.behavior.elytra.NetherPathfinderContext;
import baritone.behavior.elytra.UnpackedSegment;
@@ -33,6 +33,7 @@ import net.minecraft.entity.item.EntityFireworkRocket;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.AxisAlignedBB;
@@ -54,7 +55,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
private static final long NETHER_SEED = 146008555100680L;
// Used exclusively for PathRenderer
- public List> lines;
+ public List> clearLines;
+ public List> blockedLines;
public BlockPos aimPos;
public List visiblePath;
@@ -67,7 +69,8 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
public ElytraBehavior(Baritone baritone) {
super(baritone);
this.context = new NetherPathfinderContext(NETHER_SEED);
- this.lines = new ArrayList<>();
+ this.clearLines = new ArrayList<>();
+ this.blockedLines = new ArrayList<>();
this.visiblePath = Collections.emptyList();
this.pathManager = new PathManager();
}
@@ -79,7 +82,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
private boolean completePath;
private int playerNear;
- private int goingTo;
private boolean recalculating;
@@ -168,16 +170,15 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
private Vec3d pathAt(int i) {
return new Vec3d(
- this.path.get(i).x,
- this.path.get(i).y,
- this.path.get(i).z
+ this.path.get(i).x + 0.000123,
+ this.path.get(i).y + 0.000456,
+ this.path.get(i).z + 0.000789
);
}
public void clear() {
this.path = Collections.emptyList();
this.playerNear = 0;
- this.goingTo = 0;
this.completePath = true;
}
@@ -185,7 +186,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
this.path = segment.collect();
this.removeBacktracks();
this.playerNear = 0;
- this.goingTo = 0;
this.completePath = segment.isFinished();
}
@@ -197,14 +197,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
return this.playerNear;
}
- public void setGoingTo(int index) {
- this.goingTo = index;
- }
-
- public BetterBlockPos goingTo() {
- return this.path.get(this.goingTo);
- }
-
// mickey resigned
private CompletableFuture path0(BlockPos src, BlockPos dst, UnaryOperator operator) {
return ElytraBehavior.this.context.pathFindAsync(src, dst)
@@ -300,12 +292,19 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
@Override
public void onChunkEvent(ChunkEvent event) {
- if (event.getState() == EventState.POST && event.getType().isPopulate()) {
+ if (event.isPostPopulate()) {
final Chunk chunk = ctx.world().getChunk(event.getX(), event.getZ());
this.context.queueForPacking(chunk);
}
}
+ @Override
+ public void onBlockChange(BlockChangeEvent event) {
+ event.getAffectedChunks().stream()
+ .map(pos -> ctx.world().getChunk(pos.x, pos.z))
+ .forEach(this.context::queueForPacking);
+ }
+
public void path(BlockPos destination) {
pawsed = false;
this.pathManager.pathToDestination(destination);
@@ -342,12 +341,15 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
}
if (isPaused()) return;
this.lines.clear();
+ this.clearLines.clear();
+ this.blockedLines.clear();
final List path = this.pathManager.getPath();
if (path.isEmpty()) {
return;
}
+ this.bsi = new BlockStateInterface(ctx);
this.pathManager.tick();
final int playerNear = this.pathManager.getNear();
@@ -371,6 +373,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
final Vec3d start = ctx.playerFeetAsVec();
final boolean firework = isFireworkActive();
+ BetterBlockPos goingTo = null;
boolean forceUseFirework = false;
this.sinceFirework++;
@@ -414,8 +417,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
continue;
}
forceUseFirework = pitch.second();
-
- this.pathManager.setGoingTo(i);
+ goingTo = path.get(i);
this.aimPos = path.get(i).add(0, dy, 0);
baritone.getLookBehavior().updateTarget(new Rotation(yaw, pitch.first()), false);
break outermost;
@@ -428,7 +430,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
}
}
- final BetterBlockPos goingTo = this.pathManager.goingTo();
final boolean useOnDescend = !Baritone.settings().conserveFireworks.value || ctx.player().posY < goingTo.y + 5;
final double currentSpeed = new Vec3d(
ctx.player().motionX,
@@ -533,8 +534,18 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
}
private boolean clearView(Vec3d start, Vec3d dest) {
- lines.add(new Pair<>(start, dest));
- return !rayTraceBlocks(ctx.world(), start.x, start.y, start.z, dest.x, dest.y, dest.z);
+ boolean oxy = !rayTraceBlocks(start.x, start.y, start.z, dest.x, dest.y, dest.z);
+ boolean meow = !rayTraceBlocks(start, dest);
+ if (oxy != meow) {
+ logDirect(start + " " + dest + " " + oxy + " " + meow);
+ }
+ if (oxy) {
+ clearLines.add(new Pair<>(start, dest));
+ return true;
+ } else {
+ blockedLines.add(new Pair<>(start, dest));
+ return false;
+ }
}
private Pair solvePitch(Vec3d goalDirection, int steps, int relaxation, boolean currentlyBoosted) {
@@ -564,7 +575,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
Float bestPitch = null;
double bestDot = Double.NEGATIVE_INFINITY;
Vec3d motion = new Vec3d(ctx.player().motionX, ctx.player().motionY, ctx.player().motionZ);
- BlockStateInterface bsi = new BlockStateInterface(ctx);
float minPitch = desperate ? -90 : Math.max(good.getPitch() - Baritone.settings().elytraPitchRange.value, -89);
float maxPitch = desperate ? 90 : Math.min(good.getPitch() + Baritone.settings().elytraPitchRange.value, 89);
outer:
@@ -579,7 +589,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
for (int x = MathHelper.floor(Math.min(actualPosition.x, actualPositionPrevTick.x) - 0.31); x <= Math.max(actualPosition.x, actualPositionPrevTick.x) + 0.31; x++) {
for (int y = MathHelper.floor(Math.min(actualPosition.y, actualPositionPrevTick.y) - 0.2); y <= Math.max(actualPosition.y, actualPositionPrevTick.y) + 1; y++) {
for (int z = MathHelper.floor(Math.min(actualPosition.z, actualPositionPrevTick.z) - 0.31); z <= Math.max(actualPosition.z, actualPositionPrevTick.z) + 0.31; z++) {
- if (!passable(bsi.get0(x, y, z))) {
+ if (!this.passable(x, y, z)) {
continue outer;
}
}
@@ -597,6 +607,12 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
return bestPitch;
}
+ private BlockStateInterface bsi;
+
+ public boolean passable(int x, int y, int z) {
+ return passable(this.bsi.get0(x, y, z));
+ }
+
public static boolean passable(IBlockState state) {
return state.getMaterial() == Material.AIR;
}
@@ -652,20 +668,13 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
return new Vec3d(motionX, motionY, motionZ);
}
- private final BlockPos.MutableBlockPos mutableRaytraceBlockPos = new BlockPos.MutableBlockPos();
-
- private boolean rayTraceBlocks(final World world,
- final double startX, final double startY, final double startZ,
+ private boolean rayTraceBlocks(final double startX, final double startY, final double startZ,
final double endX, final double endY, final double endZ) {
int voxelCurrX = fastFloor(startX);
int voxelCurrY = fastFloor(startY);
int voxelCurrZ = fastFloor(startZ);
- Chunk prevChunk;
- IBlockState currentState = (prevChunk = cachedChunk(world, this.mutableRaytraceBlockPos.setPos(voxelCurrX, voxelCurrY, voxelCurrZ), null)).getBlockState(this.mutableRaytraceBlockPos);
-
- // This is true if player is standing inside of block.
- if (!passable(currentState)) {
+ if (!this.passable(voxelCurrX, voxelCurrY, voxelCurrZ)) {
return true;
}
@@ -741,8 +750,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
voxelCurrZ = (fastFloor(currPosZ) - zFloorOffset);
}
- currentState = (prevChunk = cachedChunk(world, this.mutableRaytraceBlockPos.setPos(voxelCurrX, voxelCurrY, voxelCurrZ), prevChunk)).getBlockState(this.mutableRaytraceBlockPos);
- if (!passable(currentState)) {
+ if (!this.passable(voxelCurrX, voxelCurrY, voxelCurrZ)) {
return true;
}
}
@@ -756,15 +764,98 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
return ((int) (v + FLOOR_DOUBLE_D)) - FLOOR_DOUBLE_I;
}
- private static Chunk cachedChunk(final World world,
- final BlockPos pos,
- final Chunk prevLookup) {
- final int chunkX = pos.getX() >> 4;
- final int chunkZ = pos.getZ() >> 4;
- if (prevLookup != null && prevLookup.x == chunkX && prevLookup.z == chunkZ) {
- return prevLookup;
+ private boolean rayTraceBlocks(Vec3d start, Vec3d end) {
+ int x1 = MathHelper.floor(end.x);
+ int y1 = MathHelper.floor(end.y);
+ int z1 = MathHelper.floor(end.z);
+ int x2 = MathHelper.floor(start.x);
+ int y2 = MathHelper.floor(start.y);
+ int z2 = MathHelper.floor(start.z);
+ BlockPos blockpos = new BlockPos(x2, y2, z2);
+ IBlockState iblockstate = ctx.world().getBlockState(blockpos);
+ if (!passable(iblockstate)) {
+ return true;
}
- return world.getChunk(chunkX, chunkZ);
+ int steps = 200;
+ while (steps-- >= 0) {
+ if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z)) {
+ return false;
+ }
+ if (x2 == x1 && y2 == y1 && z2 == z1) {
+ return false;
+ }
+ boolean hitX = true;
+ boolean hitY = true;
+ boolean hitZ = true;
+ double nextX = 999.0D;
+ double nextY = 999.0D;
+ double nextZ = 999.0D;
+ if (x1 > x2) {
+ nextX = (double) x2 + 1.0D;
+ } else if (x1 < x2) {
+ nextX = (double) x2 + 0.0D;
+ } else {
+ hitX = false;
+ }
+ if (y1 > y2) {
+ nextY = (double) y2 + 1.0D;
+ } else if (y1 < y2) {
+ nextY = (double) y2 + 0.0D;
+ } else {
+ hitY = false;
+ }
+ if (z1 > z2) {
+ nextZ = (double) z2 + 1.0D;
+ } else if (z1 < z2) {
+ nextZ = (double) z2 + 0.0D;
+ } else {
+ hitZ = false;
+ }
+ double stepX = 999.0D;
+ double stepY = 999.0D;
+ double stepZ = 999.0D;
+ double dirX = end.x - start.x;
+ double dirY = end.y - start.y;
+ double dirZ = end.z - start.z;
+ if (hitX) {
+ stepX = (nextX - start.x) / dirX;
+ }
+ if (hitY) {
+ stepY = (nextY - start.y) / dirY;
+ }
+ if (hitZ) {
+ stepZ = (nextZ - start.z) / dirZ;
+ }
+ if (stepX == -0.0D) {
+ stepX = -1.0E-4D;
+ }
+ if (stepY == -0.0D) {
+ stepY = -1.0E-4D;
+ }
+ if (stepZ == -0.0D) {
+ stepZ = -1.0E-4D;
+ }
+ EnumFacing dir;
+ if (stepX < stepY && stepX < stepZ) {
+ dir = x1 > x2 ? EnumFacing.WEST : EnumFacing.EAST;
+ start = new Vec3d(nextX, start.y + dirY * stepX, start.z + dirZ * stepX);
+ } else if (stepY < stepZ) {
+ dir = y1 > y2 ? EnumFacing.DOWN : EnumFacing.UP;
+ start = new Vec3d(start.x + dirX * stepY, nextY, start.z + dirZ * stepY);
+ } else {
+ dir = z1 > z2 ? EnumFacing.NORTH : EnumFacing.SOUTH;
+ start = new Vec3d(start.x + dirX * stepZ, start.y + dirY * stepZ, nextZ);
+ }
+ x2 = MathHelper.floor(start.x) - (dir == EnumFacing.EAST ? 1 : 0);
+ y2 = MathHelper.floor(start.y) - (dir == EnumFacing.UP ? 1 : 0);
+ z2 = MathHelper.floor(start.z) - (dir == EnumFacing.SOUTH ? 1 : 0);
+ blockpos = new BlockPos(x2, y2, z2);
+ IBlockState iblockstate1 = ctx.world().getBlockState(blockpos);
+ if (!passable(iblockstate1)) {
+ return true;
+ }
+ }
+ return false;
}
}
diff --git a/src/main/java/baritone/event/GameEventHandler.java b/src/main/java/baritone/event/GameEventHandler.java
index 0b46eb5e1..ceb05e739 100644
--- a/src/main/java/baritone/event/GameEventHandler.java
+++ b/src/main/java/baritone/event/GameEventHandler.java
@@ -23,8 +23,11 @@ import baritone.api.event.events.type.EventState;
import baritone.api.event.listener.IEventBus;
import baritone.api.event.listener.IGameEventListener;
import baritone.api.utils.Helper;
+import baritone.api.utils.Pair;
+import baritone.cache.CachedChunk;
import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface;
+import net.minecraft.block.state.IBlockState;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
@@ -75,13 +78,10 @@ public final class GameEventHandler implements IEventBus, Helper {
}
@Override
- public final void onChunkEvent(ChunkEvent event) {
+ public void onChunkEvent(ChunkEvent event) {
EventState state = event.getState();
ChunkEvent.Type type = event.getType();
- boolean isPostPopulate = state == EventState.POST
- && (type == ChunkEvent.Type.POPULATE_FULL || type == ChunkEvent.Type.POPULATE_PARTIAL);
-
World world = baritone.getPlayerContext().world();
// Whenever the server sends us to another dimension, chunks are unloaded
@@ -91,7 +91,7 @@ public final class GameEventHandler implements IEventBus, Helper {
&& type == ChunkEvent.Type.UNLOAD
&& world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ());
- if (isPostPopulate || isPreUnload) {
+ if (event.isPostPopulate() || isPreUnload) {
baritone.getWorldProvider().ifWorldLoaded(worldData -> {
Chunk chunk = world.getChunk(event.getX(), event.getZ());
worldData.getCachedWorld().queueForPacking(chunk);
@@ -102,6 +102,26 @@ public final class GameEventHandler implements IEventBus, Helper {
listeners.forEach(l -> l.onChunkEvent(event));
}
+ @Override
+ public void onBlockChange(BlockChangeEvent event) {
+ if (Baritone.settings().repackOnAnyBlockChange.value) {
+ final boolean keepingTrackOf = event.getBlocks().stream()
+ .map(Pair::second).map(IBlockState::getBlock)
+ .anyMatch(CachedChunk.BLOCKS_TO_KEEP_TRACK_OF::contains);
+
+ if (keepingTrackOf) {
+ baritone.getWorldProvider().ifWorldLoaded(worldData -> {
+ final World world = baritone.getPlayerContext().world();
+ event.getAffectedChunks().stream()
+ .map(pos -> world.getChunk(pos.x, pos.z))
+ .forEach(worldData.getCachedWorld()::queueForPacking);
+ });
+ }
+ }
+
+ listeners.forEach(l -> l.onBlockChange(event));
+ }
+
@Override
public final void onRenderPass(RenderEvent event) {
listeners.forEach(l -> l.onRenderPass(event));
diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java
index 7274f5dbc..d608d4a2b 100644
--- a/src/main/java/baritone/utils/PathRenderer.java
+++ b/src/main/java/baritone/utils/PathRenderer.java
@@ -108,11 +108,21 @@ public final class PathRenderer implements IRenderer {
if (elytra.aimPos != null) {
drawGoal(ctx.player(), new GoalBlock(elytra.aimPos), partialTicks, Color.GREEN);
}
- if (!elytra.lines.isEmpty() && Baritone.settings().renderRaytraces.value) {
+ if (!elytra.clearLines.isEmpty() && Baritone.settings().renderRaytraces.value) {
+ IRenderer.startLines(Color.GREEN, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value);
+ boolean orig = settings.renderPathAsLine.value;
+ settings.renderPathAsLine.value = true;
+ for (Pair line : elytra.clearLines) {
+ emitLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z);
+ }
+ settings.renderPathAsLine.value = orig;
+ IRenderer.endLines(settings.renderPathIgnoreDepth.value);
+ }
+ if (!elytra.blockedLines.isEmpty() && Baritone.settings().renderRaytraces.value) {
IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value);
boolean orig = settings.renderPathAsLine.value;
settings.renderPathAsLine.value = true;
- for (Pair line : elytra.lines) {
+ for (Pair line : elytra.blockedLines) {
emitLine(line.first().x, line.first().y, line.first().z, line.second().x, line.second().y, line.second().z);
}
settings.renderPathAsLine.value = orig;