Merge branch 'elytra' into elytra

This commit is contained in:
Brady Hahn 2023-06-18 21:39:09 -05:00 committed by GitHub
commit d2b1398cea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 311 additions and 131 deletions

View File

@ -23,6 +23,7 @@ import baritone.api.command.ICommandSystem;
import baritone.api.schematic.ISchematicSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.network.NetHandlerPlayClient;
import java.util.List;
import java.util.Objects;
@ -82,6 +83,22 @@ public interface IBaritoneProvider {
return null;
}
/**
* Provides the {@link IBaritone} instance for the player with the specified connection.
*
* @param connection The connection
* @return The {@link IBaritone} instance.
*/
default IBaritone getBaritoneForConnection(NetHandlerPlayClient connection) {
for (IBaritone baritone : this.getAllBaritones()) {
final EntityPlayerSP player = baritone.getPlayerContext().player();
if (player != null && player.connection == connection) {
return baritone;
}
}
return null;
}
/**
* Creates and registers a new {@link IBaritone} instance using the specified {@link Minecraft}. The existing
* instance is returned if already registered.

View File

@ -0,0 +1,49 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.event.events;
import baritone.api.utils.Pair;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author Brady
*/
public final class BlockChangeEvent {
private final Set<ChunkPos> affectedChunks;
private final List<Pair<BlockPos, IBlockState>> blocks;
public BlockChangeEvent(ChunkPos pos, List<Pair<BlockPos, IBlockState>> blocks) {
this.affectedChunks = Collections.singleton(pos);
this.blocks = blocks;
}
public Set<ChunkPos> getAffectedChunks() {
return this.affectedChunks;
}
public List<Pair<BlockPos, IBlockState>> getBlocks() {
return this.blocks;
}
}

View File

@ -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 {
/**

View File

@ -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) {}

View File

@ -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.
* <p>

View File

@ -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<BlockPos, IBlockState> 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();
}
}

View File

@ -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<Pair<Vec3d, Vec3d>> lines;
public List<Pair<Vec3d, Vec3d>> clearLines;
public List<Pair<Vec3d, Vec3d>> blockedLines;
public BlockPos aimPos;
public List<BetterBlockPos> 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<Void> path0(BlockPos src, BlockPos dst, UnaryOperator<UnpackedSegment> 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<BetterBlockPos> 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<Float, Boolean> 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;
}
}

View File

@ -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));

View File

@ -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<Vec3d, Vec3d> 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<Vec3d, Vec3d> line : elytra.lines) {
for (Pair<Vec3d, Vec3d> 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;