/* * 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 dev.babbaj.pathfinder.NetherPathfinder; import dev.babbaj.pathfinder.PathSegment; import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import static baritone.behavior.ElytraBehavior.passable; /** * @author Brady */ public final class NetherPathfinderContext { private final long context; private final long seed; private final ExecutorService executor; public NetherPathfinderContext(long seed) { this.context = NetherPathfinder.newContext(seed); this.seed = seed; this.executor = Executors.newSingleThreadExecutor(); } public void queueForPacking(Chunk chunk) { this.executor.submit(() -> NetherPathfinder.insertChunkData(this.context, chunk.x, chunk.z, pack(chunk))); } public CompletableFuture pathFindAsync(final BlockPos src, final BlockPos dst) { return CompletableFuture.supplyAsync(() -> NetherPathfinder.pathFind( this.context, src.getX(), src.getY(), src.getZ(), dst.getX(), dst.getY(), dst.getZ(), true, 10000 ), this.executor); } public boolean raytrace(final double startX, final double startY, final double startZ, final double endX, final double endY, final double endZ) { final boolean[] hitOut = new boolean[1]; NetherPathfinder.raytrace( this.context, true, 1, new double[] { startX, startY, startZ }, new double[] { endX, endY, endZ }, hitOut, null ); return hitOut[0]; } public void raytrace(final double[] src, final double[] dst, final boolean[] hitOut) { NetherPathfinder.raytrace(this.context, true, hitOut.length, src, dst, hitOut, null); } public boolean raytrace(final int count, final double[] src, final double[] dst, int visibility) { switch (visibility) { case Visibility.ALL: return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, false); case Visibility.NONE: return !NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true); case Visibility.ANY: return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true); } throw new IllegalArgumentException("lol"); } public void cancel() { NetherPathfinder.cancel(this.context); } public void destroy() { this.cancel(); // Ignore anything that was queued up, just shutdown the executor this.executor.shutdownNow(); try { while (!this.executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) {} } catch (InterruptedException e) { e.printStackTrace(); } NetherPathfinder.freeContext(this.context); } public long getSeed() { return this.seed; } private static boolean[] pack(Chunk chunk) { try { boolean[] packed = new boolean[16 * 16 * 128]; ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray(); for (int y0 = 0; y0 < 8; y0++) { ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0]; if (extendedblockstorage == null) { continue; } BlockStateContainer bsc = extendedblockstorage.getData(); int yReal = y0 << 4; for (int y1 = 0; y1 < 16; y1++) { int y = y1 | yReal; for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { IBlockState state = bsc.get(x, y1, z); if (!passable(state, false)) { packed[x | (z << 4) | (y << 8)] = true; } } } } } return packed; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } public static final class Visibility { private Visibility() {} public static final int ALL = 0; public static final int NONE = 1; public static final int ANY = 2; } }