diff --git a/src/api/java/baritone/api/behavior/IElytraBehavior.java b/src/api/java/baritone/api/behavior/IElytraBehavior.java index 21169b896..95ae62926 100644 --- a/src/api/java/baritone/api/behavior/IElytraBehavior.java +++ b/src/api/java/baritone/api/behavior/IElytraBehavior.java @@ -41,4 +41,14 @@ public interface IElytraBehavior extends IBehavior { * Returns {@code true} if the current {@link IElytraBehavior} is actively pathing. */ boolean isActive(); + + /** + * @return {@code true} if the native library loaded and elytra is actually usable + */ + boolean isLoaded(); + + /* + * FOR INTERNAL USE ONLY. MAY BE REMOVED AT ANY TIME. + */ + boolean isSafeToCancel(); } diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 805fb0488..970bfc0a9 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -21,6 +21,7 @@ import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.Settings; import baritone.api.behavior.IBehavior; +import baritone.api.behavior.IElytraBehavior; import baritone.api.event.listener.IEventBus; import baritone.api.process.IBaritoneProcess; import baritone.api.utils.IPlayerContext; @@ -107,7 +108,7 @@ public class Baritone implements IBaritone { { this.lookBehavior = this.registerBehavior(LookBehavior::new); - this.elytraBehavior = this.registerBehavior(ElytraBehavior::new); + this.elytraBehavior = this.registerBehavior(ElytraBehavior::create); this.pathingBehavior = this.registerBehavior(PathingBehavior::new); this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new); this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); @@ -240,7 +241,7 @@ public class Baritone implements IBaritone { } @Override - public ElytraBehavior getElytraBehavior() { + public IElytraBehavior getElytraBehavior() { return this.elytraBehavior; } diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index ec2363f29..7fc47032b 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -19,12 +19,14 @@ package baritone.behavior; import baritone.Baritone; import baritone.api.IBaritone; +import baritone.api.Settings; import baritone.api.behavior.IElytraBehavior; import baritone.api.behavior.look.IAimProcessor; import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.*; import baritone.api.event.events.type.EventState; import baritone.api.pathing.goals.Goal; +import baritone.api.pathing.goals.GoalBlock; import baritone.api.pathing.goals.GoalYLevel; import baritone.api.pathing.movement.IMovement; import baritone.api.pathing.path.IPathExecutor; @@ -33,13 +35,12 @@ import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.api.utils.*; import baritone.api.utils.input.Input; -import baritone.behavior.elytra.NetherPath; -import baritone.behavior.elytra.NetherPathfinderContext; -import baritone.behavior.elytra.PathCalculationException; -import baritone.behavior.elytra.UnpackedSegment; +import baritone.behavior.elytra.*; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.movements.MovementFall; import baritone.utils.BlockStateInterface; +import baritone.utils.IRenderer; +import baritone.utils.PathRenderer; import baritone.utils.PathingCommandContext; import baritone.utils.accessor.IChunkProviderClient; import baritone.utils.accessor.IEntityFireworkRocket; @@ -60,7 +61,9 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.world.chunk.Chunk; +import java.awt.*; import java.util.*; +import java.util.List; import java.util.concurrent.*; import java.util.function.Supplier; import java.util.function.UnaryOperator; @@ -112,7 +115,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H private Solution pendingSolution; private boolean solveNextTick; - public ElytraBehavior(Baritone baritone) { + private ElytraBehavior(Baritone baritone) { super(baritone); this.clearLines = new CopyOnWriteArrayList<>(); this.blockedLines = new CopyOnWriteArrayList<>(); @@ -369,6 +372,45 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } + @Override + public void onRenderPass(RenderEvent event) { + final Settings settings = Baritone.settings(); + if (this.visiblePath != null) { + PathRenderer.drawPath(this.visiblePath, 0, Color.RED, false, 0, 0, 0.0D); + } + if (this.aimPos != null) { + PathRenderer.drawGoal(ctx.player(), new GoalBlock(this.aimPos), event.getPartialTicks(), Color.GREEN); + } + if (!this.clearLines.isEmpty() && settings.renderRaytraces.value) { + IRenderer.startLines(Color.GREEN, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); + for (Pair line : this.clearLines) { + IRenderer.emitLine(line.first(), line.second()); + } + IRenderer.endLines(settings.renderPathIgnoreDepth.value); + } + if (!this.blockedLines.isEmpty() && Baritone.settings().renderRaytraces.value) { + IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); + for (Pair line : this.blockedLines) { + IRenderer.emitLine(line.first(), line.second()); + } + IRenderer.endLines(settings.renderPathIgnoreDepth.value); + } + if (this.simulationLine != null && Baritone.settings().renderElytraSimulation.value) { + IRenderer.startLines(new Color(0x36CCDC), settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); + final Vec3d offset = new Vec3d( + ctx.player().prevPosX + (ctx.player().posX - ctx.player().prevPosX) * event.getPartialTicks(), + ctx.player().prevPosY + (ctx.player().posY - ctx.player().prevPosY) * event.getPartialTicks(), + ctx.player().prevPosZ + (ctx.player().posZ - ctx.player().prevPosZ) * event.getPartialTicks() + ); + for (int i = 0; i < this.simulationLine.size() - 1; i++) { + final Vec3d src = this.simulationLine.get(i).add(offset); + final Vec3d dst = this.simulationLine.get(i + 1).add(offset); + IRenderer.emitLine(src, dst); + } + IRenderer.endLines(settings.renderPathIgnoreDepth.value); + } + } + @Override public void onWorldEvent(WorldEvent event) { if (event.getWorld() != null) { @@ -451,6 +493,16 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H .filter(process -> this.process == process).isPresent(); } + @Override + public boolean isLoaded() { + return true; + } + + @Override + public boolean isSafeToCancel() { + return !this.isActive() || !(this.process.state == State.FLYING || this.process.state == State.START_FLYING); + } + @Override public void onTick(final TickEvent event) { if (event.getType() == TickEvent.Type.OUT) { @@ -1261,10 +1313,6 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H } } - public boolean isSafeToCancel() { - return !this.isActive() || !(this.process.state == State.FLYING || this.process.state == State.START_FLYING); - } - private final class ElytraProcess implements IBaritoneProcess { private State state; @@ -1443,4 +1491,10 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H START_FLYING, FLYING } + + public static T create(final Baritone baritone) { + return (T) (NetherPathfinderContext.isSupported() + ? new ElytraBehavior(baritone) + : new NullElytraBehavior(baritone)); + } } diff --git a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java index a30cb4aa1..9bbb2a24a 100644 --- a/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java +++ b/src/main/java/baritone/behavior/elytra/NetherPathfinderContext.java @@ -222,4 +222,8 @@ public final class NetherPathfinderContext { private Visibility() {} } + + public static boolean isSupported() { + return NetherPathfinder.isThisSystemSupported(); + } } diff --git a/src/main/java/baritone/behavior/elytra/NullElytraBehavior.java b/src/main/java/baritone/behavior/elytra/NullElytraBehavior.java new file mode 100644 index 000000000..b173d82b8 --- /dev/null +++ b/src/main/java/baritone/behavior/elytra/NullElytraBehavior.java @@ -0,0 +1,70 @@ +/* + * 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 . + */ + +package baritone.behavior.elytra; + +import baritone.Baritone; +import baritone.api.behavior.IElytraBehavior; +import baritone.behavior.Behavior; +import net.minecraft.util.math.BlockPos; + +import java.util.concurrent.CompletableFuture; + +/** + * @author Brady + */ +public final class NullElytraBehavior extends Behavior implements IElytraBehavior { + + public NullElytraBehavior(Baritone baritone) { + super(baritone); + } + + @Override + public CompletableFuture resetContext() { + throw new UnsupportedOperationException("Called resetContext() on NullElytraBehavior"); + } + + @Override + public void repackChunks() { + throw new UnsupportedOperationException("Called repackChunks() on NullElytraBehavior"); + } + + @Override + public void pathTo(BlockPos destination) { + throw new UnsupportedOperationException("Called pathTo() on NullElytraBehavior"); + } + + @Override + public void cancel() { + throw new UnsupportedOperationException("Called cancel() on NullElytraBehavior"); + } + + @Override + public boolean isActive() { + return false; + } + + @Override + public boolean isLoaded() { + return false; + } + + @Override + public boolean isSafeToCancel() { + return true; + } +} diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index de8cbadef..252559b75 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -43,6 +43,17 @@ public class ElytraCommand extends Command { public void execute(String label, IArgConsumer args) throws CommandException { final ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess(); final IElytraBehavior elytra = baritone.getElytraBehavior(); + if (!elytra.isLoaded()) { + final String osArch = System.getProperty("os.arch"); + final String osName = System.getProperty("os.name"); + throw new CommandInvalidStateException(String.format( + "legacy architectures are not supported. your CPU is %s and your operating system is %s." + + "supported architectures are x86_64 or arm64, supported operating systems are windows," + + "linux, and mac", + osArch, osName + )); + } + if (!args.hasAny()) { Goal iGoal = customGoalProcess.mostRecentGoal(); if (iGoal == null) { diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index 680d7e380..3fd5c2556 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -27,6 +27,7 @@ import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.Vec3d; import java.awt.*; @@ -120,4 +121,16 @@ public interface IRenderer { emitAABB(aabb); tessellator.draw(); } + + static void emitLine(Vec3d start, Vec3d end) { + emitLine(start.x, start.y, start.z, end.x, end.y, end.z); + } + + static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { + double vpX = renderManager.viewerPosX; + double vpY = renderManager.viewerPosY; + double vpZ = renderManager.viewerPosZ; + buffer.pos(x1 - vpX, y1 - vpY, z1 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + buffer.pos(x2 - vpX, y2 - vpY, z2 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); + } } diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index eb7615de8..0fcad054a 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -17,15 +17,12 @@ package baritone.utils; -import baritone.Baritone; import baritone.api.BaritoneAPI; import baritone.api.event.events.RenderEvent; import baritone.api.pathing.goals.*; import baritone.api.utils.BetterBlockPos; import baritone.api.utils.IPlayerContext; -import baritone.api.utils.Pair; import baritone.api.utils.interfaces.IGoalRenderPos; -import baritone.behavior.ElytraBehavior; import baritone.behavior.PathingBehavior; import baritone.pathing.path.PathExecutor; import net.minecraft.block.state.IBlockState; @@ -102,44 +99,6 @@ public final class PathRenderer implements IRenderer { drawPath(next.getPath().positions(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20); } - final ElytraBehavior elytra = behavior.baritone.getElytraBehavior(); - - if (elytra.visiblePath != null) { - drawPath(elytra.visiblePath, 0, Color.RED, false, 0, 0, 0.0D); - } - if (elytra.aimPos != null) { - drawGoal(ctx.player(), new GoalBlock(elytra.aimPos), partialTicks, Color.GREEN); - } - if (!elytra.clearLines.isEmpty() && Baritone.settings().renderRaytraces.value) { - IRenderer.startLines(Color.GREEN, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); - for (Pair line : elytra.clearLines) { - emitLine(line.first(), line.second()); - } - IRenderer.endLines(settings.renderPathIgnoreDepth.value); - } - if (!elytra.blockedLines.isEmpty() && Baritone.settings().renderRaytraces.value) { - IRenderer.startLines(Color.BLUE, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); - for (Pair line : elytra.blockedLines) { - emitLine(line.first(), line.second()); - } - IRenderer.endLines(settings.renderPathIgnoreDepth.value); - } - if (elytra.simulationLine != null && Baritone.settings().renderElytraSimulation.value) { - IRenderer.startLines(new Color(0x36CCDC), settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); - final Vec3d offset = new Vec3d( - ctx.player().prevPosX + (ctx.player().posX - ctx.player().prevPosX) * partialTicks, - ctx.player().prevPosY + (ctx.player().posY - ctx.player().prevPosY) * partialTicks, - ctx.player().prevPosZ + (ctx.player().posZ - ctx.player().prevPosZ) * partialTicks - ); - for (int i = 0; i < elytra.simulationLine.size() - 1; i++) { - final Vec3d src = elytra.simulationLine.get(i).add(offset); - final Vec3d dst = elytra.simulationLine.get(i + 1).add(offset); - emitLine(src, dst); - } - IRenderer.endLines(settings.renderPathIgnoreDepth.value); - } - - // If there is a path calculation currently running, render the path calculation process behavior.getInProgress().ifPresent(currentlyRunning -> { currentlyRunning.bestPathSoFar().ifPresent(p -> { @@ -153,11 +112,11 @@ public final class PathRenderer implements IRenderer { }); } - private static void drawPath(List positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { + public static void drawPath(List positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { drawPath(positions, startIndex, color, fadeOut, fadeStart0, fadeEnd0, 0.5D); } - private static void drawPath(List positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0, double offset) { + public static void drawPath(List positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0, double offset) { IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); int fadeStart = fadeStart0 + startIndex; @@ -199,18 +158,6 @@ public final class PathRenderer implements IRenderer { IRenderer.endLines(settings.renderPathIgnoreDepth.value); } - private static void emitLine(Vec3d start, Vec3d end) { - emitLine(start.x, start.y, start.z, end.x, end.y, end.z); - } - - private static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { - double vpX = renderManager.viewerPosX; - double vpY = renderManager.viewerPosY; - double vpZ = renderManager.viewerPosZ; - buffer.pos(x1 - vpX, y1 - vpY, z1 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - buffer.pos(x2 - vpX, y2 - vpY, z2 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); - } - private static void emitPathLine(double x1, double y1, double z1, double x2, double y2, double z2, double offset) { final double extraOffset = offset + 0.03D; double vpX = renderManager.viewerPosX; @@ -255,7 +202,7 @@ public final class PathRenderer implements IRenderer { IRenderer.endLines(settings.renderSelectionBoxesIgnoreDepth.value); } - private static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) { + public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) { drawGoal(player, goal, partialTicks, color, true); }