diff --git a/src/api/java/baritone/api/IBaritoneProvider.java b/src/api/java/baritone/api/IBaritoneProvider.java index 84a8abbbd..55d208e03 100644 --- a/src/api/java/baritone/api/IBaritoneProvider.java +++ b/src/api/java/baritone/api/IBaritoneProvider.java @@ -21,6 +21,7 @@ import baritone.api.cache.IWorldScanner; import baritone.api.command.ICommand; import baritone.api.command.ICommandSystem; import baritone.api.schematic.ISchematicSystem; +import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import java.util.List; @@ -52,15 +53,13 @@ public interface IBaritoneProvider { List getAllBaritones(); /** - * Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be - * replaced with or be overloaded in addition to {@code #getBaritoneForUser(IBaritoneUser)} when - * {@code bot-system} is merged into {@code master}. + * Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. * * @param player The player * @return The {@link IBaritone} instance. */ default IBaritone getBaritoneForPlayer(EntityPlayerSP player) { - for (IBaritone baritone : getAllBaritones()) { + for (IBaritone baritone : this.getAllBaritones()) { if (Objects.equals(player, baritone.getPlayerContext().player())) { return baritone; } @@ -68,6 +67,39 @@ public interface IBaritoneProvider { return null; } + /** + * Provides the {@link IBaritone} instance for a given {@link Minecraft}. + * + * @param minecraft The minecraft + * @return The {@link IBaritone} instance. + */ + default IBaritone getBaritoneForMinecraft(Minecraft minecraft) { + for (IBaritone baritone : this.getAllBaritones()) { + if (Objects.equals(minecraft, baritone.getPlayerContext().minecraft())) { + 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. + * + * @param minecraft The minecraft + * @return The {@link IBaritone} instance + */ + IBaritone createBaritone(Minecraft minecraft); + + /** + * Destroys and removes the specified {@link IBaritone} instance. If the specified instance is the + * {@link #getPrimaryBaritone() primary baritone}, this operation has no effect and will return {@code false}. + * + * @param baritone The baritone instance to remove + * @return Whether the baritone instance was removed + */ + boolean destroyBaritone(IBaritone baritone); + /** * Returns the {@link IWorldScanner} instance. This is not a type returned by * {@link IBaritone} implementation, because it is not linked with {@link IBaritone}. diff --git a/src/api/java/baritone/api/cache/IWorldProvider.java b/src/api/java/baritone/api/cache/IWorldProvider.java index 0e54ef469..b9ca149c7 100644 --- a/src/api/java/baritone/api/cache/IWorldProvider.java +++ b/src/api/java/baritone/api/cache/IWorldProvider.java @@ -17,6 +17,8 @@ package baritone.api.cache; +import java.util.function.Consumer; + /** * @author Brady * @since 9/24/2018 @@ -29,4 +31,11 @@ public interface IWorldProvider { * @return The current world data */ IWorldData getCurrentWorld(); + + default void ifWorldLoaded(Consumer callback) { + final IWorldData currentWorld = this.getCurrentWorld(); + if (currentWorld != null) { + callback.accept(currentWorld); + } + } } diff --git a/src/api/java/baritone/api/command/datatypes/RelativeFile.java b/src/api/java/baritone/api/command/datatypes/RelativeFile.java index 0bc3604ab..ec605c048 100644 --- a/src/api/java/baritone/api/command/datatypes/RelativeFile.java +++ b/src/api/java/baritone/api/command/datatypes/RelativeFile.java @@ -19,6 +19,8 @@ package baritone.api.command.datatypes; import baritone.api.command.argument.IArgConsumer; import baritone.api.command.exception.CommandException; +import baritone.api.utils.Helper; +import net.minecraft.client.Minecraft; import java.io.File; import java.io.IOException; @@ -93,8 +95,13 @@ public enum RelativeFile implements IDatatypePost { .filter(s -> !s.contains(" ")); } + @Deprecated public static File gameDir() { - File gameDir = HELPER.mc.gameDir.getAbsoluteFile(); + return gameDir(Helper.mc); + } + + public static File gameDir(Minecraft mc) { + File gameDir = mc.gameDir.getAbsoluteFile(); if (gameDir.getName().equals(".")) { return gameDir.getParentFile(); } diff --git a/src/api/java/baritone/api/process/IBuilderProcess.java b/src/api/java/baritone/api/process/IBuilderProcess.java index c63113cdd..29d8968a7 100644 --- a/src/api/java/baritone/api/process/IBuilderProcess.java +++ b/src/api/java/baritone/api/process/IBuilderProcess.java @@ -51,6 +51,7 @@ public interface IBuilderProcess extends IBaritoneProcess { */ boolean build(String name, File schematic, Vec3i origin); + @Deprecated default boolean build(String schematicFile, BlockPos origin) { File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile); return build(schematicFile, file, origin); diff --git a/src/api/java/baritone/api/utils/Helper.java b/src/api/java/baritone/api/utils/Helper.java index 9bed37383..b99074ae0 100755 --- a/src/api/java/baritone/api/utils/Helper.java +++ b/src/api/java/baritone/api/utils/Helper.java @@ -42,8 +42,10 @@ public interface Helper { Helper HELPER = new Helper() {}; /** - * Instance of the game + * The main game instance returned by {@link Minecraft#getMinecraft()}. + * Deprecated since {@link IPlayerContext#minecraft()} should be used instead (In the majority of cases). */ + @Deprecated Minecraft mc = Minecraft.getMinecraft(); static ITextComponent getPrefix() { @@ -70,7 +72,7 @@ public interface Helper { * @param message The message to display in the popup */ default void logToast(ITextComponent title, ITextComponent message) { - mc.addScheduledTask(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message)); + Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message)); } /** @@ -131,7 +133,7 @@ public interface Helper { * @param error Whether to log as an error */ default void logNotificationDirect(String message, boolean error) { - mc.addScheduledTask(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error)); + Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error)); } /** @@ -168,7 +170,7 @@ public interface Helper { if (logAsToast) { logToast(getPrefix(), component); } else { - mc.addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component)); + Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component)); } } diff --git a/src/api/java/baritone/api/utils/IPlayerContext.java b/src/api/java/baritone/api/utils/IPlayerContext.java index fcc4c81cc..14ca69fb9 100644 --- a/src/api/java/baritone/api/utils/IPlayerContext.java +++ b/src/api/java/baritone/api/utils/IPlayerContext.java @@ -19,6 +19,7 @@ package baritone.api.utils; import baritone.api.cache.IWorldData; import net.minecraft.block.BlockSlab; +import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; @@ -33,6 +34,8 @@ import java.util.Optional; */ public interface IPlayerContext { + Minecraft minecraft(); + EntityPlayerSP player(); IPlayerController playerController(); @@ -72,6 +75,8 @@ public interface IPlayerContext { return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ); } + BetterBlockPos viewerPos(); + default Rotation playerRotations() { return new Rotation(player().rotationYaw, player().rotationPitch); } diff --git a/src/api/java/baritone/api/utils/SettingsUtil.java b/src/api/java/baritone/api/utils/SettingsUtil.java index 0b9c64737..efc080cf5 100644 --- a/src/api/java/baritone/api/utils/SettingsUtil.java +++ b/src/api/java/baritone/api/utils/SettingsUtil.java @@ -20,6 +20,7 @@ package baritone.api.utils; import baritone.api.BaritoneAPI; import baritone.api.Settings; import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; import net.minecraft.item.Item; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.Vec3i; @@ -44,8 +45,6 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import static net.minecraft.client.Minecraft.getMinecraft; - public class SettingsUtil { public static final String SETTINGS_DEFAULT_NAME = "settings.txt"; @@ -105,7 +104,7 @@ public class SettingsUtil { } private static Path settingsByName(String name) { - return getMinecraft().gameDir.toPath().resolve("baritone").resolve(name); + return Minecraft.getMinecraft().gameDir.toPath().resolve("baritone").resolve(name); } public static List modifiedSettings(Settings settings) { diff --git a/src/api/java/baritone/api/utils/gui/BaritoneToast.java b/src/api/java/baritone/api/utils/gui/BaritoneToast.java index eb6361478..9e9a6403c 100644 --- a/src/api/java/baritone/api/utils/gui/BaritoneToast.java +++ b/src/api/java/baritone/api/utils/gui/BaritoneToast.java @@ -17,6 +17,7 @@ package baritone.api.utils.gui; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.toasts.GuiToast; import net.minecraft.client.gui.toasts.IToast; import net.minecraft.client.renderer.GlStateManager; @@ -73,6 +74,6 @@ public class BaritoneToast implements IToast { } public static void addOrUpdate(ITextComponent title, ITextComponent subtitle) { - addOrUpdate(net.minecraft.client.Minecraft.getMinecraft().getToastGui(), title, subtitle, baritone.api.BaritoneAPI.getSettings().toastTimer.value); + addOrUpdate(Minecraft.getMinecraft().getToastGui(), title, subtitle, baritone.api.BaritoneAPI.getSettings().toastTimer.value); } } diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 61db54211..776e646af 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -20,8 +20,9 @@ package baritone; import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.Settings; +import baritone.api.behavior.IBehavior; import baritone.api.event.listener.IEventBus; -import baritone.api.utils.Helper; +import baritone.api.process.IBaritoneProcess; import baritone.api.utils.IPlayerContext; import baritone.behavior.*; import baritone.cache.WorldProvider; @@ -33,16 +34,17 @@ import baritone.utils.BlockStateInterface; import baritone.utils.GuiClick; import baritone.utils.InputOverrideHandler; import baritone.utils.PathingControlManager; -import baritone.utils.player.PrimaryPlayerContext; +import baritone.utils.player.BaritonePlayerContext; import net.minecraft.client.Minecraft; -import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.util.concurrent.Executor; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.function.Function; /** * @author Brady @@ -50,89 +52,101 @@ import java.util.concurrent.TimeUnit; */ public class Baritone implements IBaritone { - private static ThreadPoolExecutor threadPool; - private static File dir; + private static final ThreadPoolExecutor threadPool; static { threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>()); - - dir = new File(Minecraft.getMinecraft().gameDir, "baritone"); - if (!Files.exists(dir.toPath())) { - try { - Files.createDirectories(dir.toPath()); - } catch (IOException ignored) {} - } } - private GameEventHandler gameEventHandler; + private final Minecraft mc; + private final Path directory; - private PathingBehavior pathingBehavior; - private LookBehavior lookBehavior; - private InventoryBehavior inventoryBehavior; - private WaypointBehavior waypointBehavior; - private InputOverrideHandler inputOverrideHandler; + private final GameEventHandler gameEventHandler; - private FollowProcess followProcess; - private MineProcess mineProcess; - private GetToBlockProcess getToBlockProcess; - private CustomGoalProcess customGoalProcess; - private BuilderProcess builderProcess; - private ExploreProcess exploreProcess; - private BackfillProcess backfillProcess; - private FarmProcess farmProcess; - private InventoryPauserProcess inventoryPauserProcess; + private final PathingBehavior pathingBehavior; + private final LookBehavior lookBehavior; + private final InventoryBehavior inventoryBehavior; + private final InputOverrideHandler inputOverrideHandler; - private PathingControlManager pathingControlManager; - private SelectionManager selectionManager; - private CommandManager commandManager; + private final FollowProcess followProcess; + private final MineProcess mineProcess; + private final GetToBlockProcess getToBlockProcess; + private final CustomGoalProcess customGoalProcess; + private final BuilderProcess builderProcess; + private final ExploreProcess exploreProcess; + private final FarmProcess farmProcess; + private final InventoryPauserProcess inventoryPauserProcess; - private IPlayerContext playerContext; - private WorldProvider worldProvider; + private final PathingControlManager pathingControlManager; + private final SelectionManager selectionManager; + private final CommandManager commandManager; + + private final IPlayerContext playerContext; + private final WorldProvider worldProvider; public BlockStateInterface bsi; - Baritone() { + Baritone(Minecraft mc) { + this.mc = mc; this.gameEventHandler = new GameEventHandler(this); + this.directory = mc.gameDir.toPath().resolve("baritone"); + if (!Files.exists(this.directory)) { + try { + Files.createDirectories(this.directory); + } catch (IOException ignored) {} + } + // Define this before behaviors try and get it, or else it will be null and the builds will fail! - this.playerContext = PrimaryPlayerContext.INSTANCE; + this.playerContext = new BaritonePlayerContext(this, mc); { - // the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist - pathingBehavior = new PathingBehavior(this); - lookBehavior = new LookBehavior(this); - inventoryBehavior = new InventoryBehavior(this); - inputOverrideHandler = new InputOverrideHandler(this); - waypointBehavior = new WaypointBehavior(this); + this.pathingBehavior = this.registerBehavior(PathingBehavior::new); + this.lookBehavior = this.registerBehavior(LookBehavior::new); + this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new); + this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); + this.registerBehavior(WaypointBehavior::new); } this.pathingControlManager = new PathingControlManager(this); { - this.pathingControlManager.registerProcess(followProcess = new FollowProcess(this)); - this.pathingControlManager.registerProcess(mineProcess = new MineProcess(this)); - this.pathingControlManager.registerProcess(customGoalProcess = new CustomGoalProcess(this)); // very high iq - this.pathingControlManager.registerProcess(getToBlockProcess = new GetToBlockProcess(this)); - this.pathingControlManager.registerProcess(builderProcess = new BuilderProcess(this)); - this.pathingControlManager.registerProcess(exploreProcess = new ExploreProcess(this)); - this.pathingControlManager.registerProcess(backfillProcess = new BackfillProcess(this)); - this.pathingControlManager.registerProcess(farmProcess = new FarmProcess(this)); - this.pathingControlManager.registerProcess(inventoryPauserProcess = new InventoryPauserProcess(this)); + this.followProcess = this.registerProcess(FollowProcess::new); + this.mineProcess = this.registerProcess(MineProcess::new); + this.customGoalProcess = this.registerProcess(CustomGoalProcess::new); // very high iq + this.getToBlockProcess = this.registerProcess(GetToBlockProcess::new); + this.builderProcess = this.registerProcess(BuilderProcess::new); + this.exploreProcess = this.registerProcess(ExploreProcess::new); + this.farmProcess = this.registerProcess(FarmProcess::new); + this.inventoryPauserProcess = this.registerProcess(InventoryPauserProcess::new); + this.registerProcess(BackfillProcess::new); } - this.worldProvider = new WorldProvider(); + this.worldProvider = new WorldProvider(this); this.selectionManager = new SelectionManager(this); this.commandManager = new CommandManager(this); } + public void registerBehavior(IBehavior behavior) { + this.gameEventHandler.registerEventListener(behavior); + } + + public T registerBehavior(Function constructor) { + final T behavior = constructor.apply(this); + this.registerBehavior(behavior); + return behavior; + } + + public T registerProcess(Function constructor) { + final T behavior = constructor.apply(this); + this.pathingControlManager.registerProcess(behavior); + return behavior; + } + @Override public PathingControlManager getPathingControlManager() { return this.pathingControlManager; } - public void registerBehavior(Behavior behavior) { - this.gameEventHandler.registerEventListener(behavior); - } - @Override public InputOverrideHandler getInputOverrideHandler() { return this.inputOverrideHandler; @@ -172,6 +186,7 @@ public class Baritone implements IBaritone { return this.lookBehavior; } + @Override public ExploreProcess getExploreProcess() { return this.exploreProcess; } @@ -181,6 +196,7 @@ public class Baritone implements IBaritone { return this.mineProcess; } + @Override public FarmProcess getFarmProcess() { return this.farmProcess; } @@ -219,19 +235,19 @@ public class Baritone implements IBaritone { new Thread(() -> { try { Thread.sleep(100); - Helper.mc.addScheduledTask(() -> Helper.mc.displayGuiScreen(new GuiClick())); + mc.addScheduledTask(() -> mc.displayGuiScreen(new GuiClick())); } catch (Exception ignored) {} }).start(); } + public Path getDirectory() { + return this.directory; + } + public static Settings settings() { return BaritoneAPI.getSettings(); } - public static File getDir() { - return dir; - } - public static Executor getExecutor() { return threadPool; } diff --git a/src/main/java/baritone/BaritoneProvider.java b/src/main/java/baritone/BaritoneProvider.java index c49c02e10..b96cf03f7 100644 --- a/src/main/java/baritone/BaritoneProvider.java +++ b/src/main/java/baritone/BaritoneProvider.java @@ -23,13 +23,14 @@ import baritone.api.cache.IWorldScanner; import baritone.api.command.ICommandSystem; import baritone.api.schematic.ISchematicSystem; import baritone.cache.FasterWorldScanner; -import baritone.cache.WorldScanner; import baritone.command.CommandSystem; import baritone.command.ExampleBaritoneControl; import baritone.utils.schematic.SchematicSystem; +import net.minecraft.client.Minecraft; import java.util.Collections; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; /** * @author Brady @@ -37,25 +38,40 @@ import java.util.List; */ public final class BaritoneProvider implements IBaritoneProvider { - private final Baritone primary; private final List all; + private final List allView; - { - this.primary = new Baritone(); - this.all = Collections.singletonList(this.primary); + public BaritoneProvider() { + this.all = new CopyOnWriteArrayList<>(); + this.allView = Collections.unmodifiableList(this.all); // Setup chat control, just for the primary instance - new ExampleBaritoneControl(this.primary); + final Baritone primary = (Baritone) this.createBaritone(Minecraft.getMinecraft()); + primary.registerBehavior(ExampleBaritoneControl::new); } @Override public IBaritone getPrimaryBaritone() { - return primary; + return this.all.get(0); } @Override public List getAllBaritones() { - return all; + return this.allView; + } + + @Override + public synchronized IBaritone createBaritone(Minecraft minecraft) { + IBaritone baritone = this.getBaritoneForMinecraft(minecraft); + if (baritone == null) { + this.all.add(baritone = new Baritone(minecraft)); + } + return baritone; + } + + @Override + public synchronized boolean destroyBaritone(IBaritone baritone) { + return baritone != this.getPrimaryBaritone() && this.all.remove(baritone); } @Override diff --git a/src/main/java/baritone/behavior/Behavior.java b/src/main/java/baritone/behavior/Behavior.java index 36273c026..848beb298 100644 --- a/src/main/java/baritone/behavior/Behavior.java +++ b/src/main/java/baritone/behavior/Behavior.java @@ -35,6 +35,5 @@ public class Behavior implements IBehavior { protected Behavior(Baritone baritone) { this.baritone = baritone; this.ctx = baritone.getPlayerContext(); - baritone.registerBehavior(this); } } diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 99e496e6f..67aa45e39 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -164,19 +164,19 @@ public final class LookBehavior extends Behavior implements ILookBehavior { return pitch; } - private static float calculateMouseMove(float current, float target) { + private float calculateMouseMove(float current, float target) { final float delta = target - current; final int deltaPx = angleToMouse(delta); return current + mouseToAngle(deltaPx); } - private static int angleToMouse(float angleDelta) { + private int angleToMouse(float angleDelta) { final float minAngleChange = mouseToAngle(1); return Math.round(angleDelta / minAngleChange); } - private static float mouseToAngle(int mouseDelta) { - final float f = Helper.mc.gameSettings.mouseSensitivity * 0.6f + 0.2f; + private float mouseToAngle(int mouseDelta) { + final float f = ctx.minecraft().gameSettings.mouseSensitivity * 0.6f + 0.2f; return mouseDelta * f * f * f * 8.0f * 0.15f; } diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 33ef14ef2..31a884622 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -239,11 +239,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, if (current != null) { switch (event.getState()) { case PRE: - lastAutoJump = mc.gameSettings.autoJump; - mc.gameSettings.autoJump = false; + lastAutoJump = ctx.minecraft().gameSettings.autoJump; + ctx.minecraft().gameSettings.autoJump = false; break; case POST: - mc.gameSettings.autoJump = lastAutoJump; + ctx.minecraft().gameSettings.autoJump = lastAutoJump; break; default: break; diff --git a/src/main/java/baritone/cache/WorldProvider.java b/src/main/java/baritone/cache/WorldProvider.java index 97b15a137..59f671c99 100644 --- a/src/main/java/baritone/cache/WorldProvider.java +++ b/src/main/java/baritone/cache/WorldProvider.java @@ -19,103 +19,85 @@ package baritone.cache; import baritone.Baritone; import baritone.api.cache.IWorldProvider; -import baritone.api.utils.Helper; +import baritone.api.utils.IPlayerContext; import baritone.utils.accessor.IAnvilChunkLoader; import baritone.utils.accessor.IChunkProviderServer; -import net.minecraft.server.integrated.IntegratedServer; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.util.Tuple; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import org.apache.commons.lang3.SystemUtils; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import java.util.Map; -import java.util.function.Consumer; +import java.util.Optional; /** * @author Brady * @since 8/4/2018 */ -public class WorldProvider implements IWorldProvider, Helper { +public class WorldProvider implements IWorldProvider { - private static final Map worldCache = new HashMap<>(); // this is how the bots have the same cached world + private static final Map worldCache = new HashMap<>(); + private final Baritone baritone; + private final IPlayerContext ctx; private WorldData currentWorld; - private World mcWorld; // this let's us detect a broken load/unload hook + + /** + * This lets us detect a broken load/unload hook. + * @see #detectAndHandleBrokenLoading() + */ + private World mcWorld; + + public WorldProvider(Baritone baritone) { + this.baritone = baritone; + this.ctx = baritone.getPlayerContext(); + } @Override public final WorldData getCurrentWorld() { - detectAndHandleBrokenLoading(); + this.detectAndHandleBrokenLoading(); return this.currentWorld; } /** * Called when a new world is initialized to discover the * - * @param dimension The ID of the world's dimension + * @param world The new world */ - public final void initWorld(int dimension) { - File directory; - File readme; + public final void initWorld(World world) { + this.getSaveDirectories(world).ifPresent(dirs -> { + final Path worldDir = dirs.getFirst(); + final Path readmeDir = dirs.getSecond(); - IntegratedServer integratedServer = mc.getIntegratedServer(); - - // If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file - if (mc.isSingleplayer()) { - WorldServer localServerWorld = integratedServer.getWorld(dimension); - IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider(); - IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader(); - directory = loader.getChunkSaveLocation(); - - // Gets the "depth" of this directory relative the the game's run directory, 2 is the location of the world - if (directory.toPath().relativize(mc.gameDir.toPath()).getNameCount() != 2) { - // subdirectory of the main save directory for this world - directory = directory.getParentFile(); - } - - directory = new File(directory, "baritone"); - readme = directory; - } else { // Otherwise, the server must be remote... - String folderName; - if (mc.getCurrentServerData() != null) { - folderName = mc.getCurrentServerData().serverIP; - } else { - //replaymod causes null currentServerData and false singleplayer. - System.out.println("World seems to be a replay. Not loading Baritone cache."); - currentWorld = null; - mcWorld = mc.world; - return; - } - if (SystemUtils.IS_OS_WINDOWS) { - folderName = folderName.replace(":", "_"); - } - directory = new File(Baritone.getDir(), folderName); - readme = Baritone.getDir(); - } - - // lol wtf is this baritone folder in my minecraft save? - try (FileOutputStream out = new FileOutputStream(new File(readme, "readme.txt"))) { - // good thing we have a readme - out.write("https://github.com/cabaletta/baritone\n".getBytes()); - } catch (IOException ignored) {} - - // We will actually store the world data in a subfolder: "DIM" - Path dir = new File(directory, "DIM" + dimension).toPath(); - if (!Files.exists(dir)) { try { - Files.createDirectories(dir); + // lol wtf is this baritone folder in my minecraft save? + // good thing we have a readme + Files.createDirectories(readmeDir); + Files.write( + readmeDir.resolve("readme.txt"), + "https://github.com/cabaletta/baritone\n".getBytes(StandardCharsets.US_ASCII) + ); } catch (IOException ignored) {} - } - System.out.println("Baritone world data dir: " + dir); - synchronized (worldCache) { - this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension)); - } - this.mcWorld = mc.world; + // We will actually store the world data in a subfolder: "DIM" + final Path worldDataDir = this.getWorldDataDirectory(worldDir, world); + try { + Files.createDirectories(worldDataDir); + } catch (IOException ignored) {} + + System.out.println("Baritone world data dir: " + worldDataDir); + synchronized (worldCache) { + final int dimension = world.provider.getDimensionType().getId(); + this.currentWorld = worldCache.computeIfAbsent(worldDataDir, d -> new WorldData(d, dimension)); + } + this.mcWorld = ctx.world(); + }); } public final void closeWorld() { @@ -128,26 +110,75 @@ public class WorldProvider implements IWorldProvider, Helper { world.onClose(); } - public final void ifWorldLoaded(Consumer currentWorldConsumer) { - detectAndHandleBrokenLoading(); - if (this.currentWorld != null) { - currentWorldConsumer.accept(this.currentWorld); - } + private Path getWorldDataDirectory(Path parent, World world) { + return parent.resolve("DIM" + world.provider.getDimensionType().getId()); } - private final void detectAndHandleBrokenLoading() { - if (this.mcWorld != mc.world) { + /** + * @param world The world + * @return An {@link Optional} containing the world's baritone dir and readme dir, or {@link Optional#empty()} if + * the world isn't valid for caching. + */ + private Optional> getSaveDirectories(World world) { + Path worldDir; + Path readmeDir; + + // If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file + if (ctx.minecraft().isSingleplayer()) { + final int dimension = world.provider.getDimensionType().getId(); + final WorldServer localServerWorld = ctx.minecraft().getIntegratedServer().getWorld(dimension); + final IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider(); + final IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader(); + worldDir = loader.getChunkSaveLocation().toPath(); + + // Gets the "depth" of this directory relative to the game's run directory, 2 is the location of the world + if (worldDir.relativize(ctx.minecraft().gameDir.toPath()).getNameCount() != 2) { + // subdirectory of the main save directory for this world + worldDir = worldDir.getParent(); + } + + worldDir = worldDir.resolve("baritone"); + readmeDir = worldDir; + } else { // Otherwise, the server must be remote... + String folderName; + final ServerData serverData = ctx.minecraft().getCurrentServerData(); + if (serverData != null) { + folderName = serverData.serverIP; + } else { + //replaymod causes null currentServerData and false singleplayer. + System.out.println("World seems to be a replay. Not loading Baritone cache."); + currentWorld = null; + mcWorld = ctx.world(); + return Optional.empty(); + } + if (SystemUtils.IS_OS_WINDOWS) { + folderName = folderName.replace(":", "_"); + } + // TODO: This should probably be in "baritone/servers" + worldDir = baritone.getDirectory().resolve(folderName); + // Just write the readme to the baritone directory instead of each server save in it + readmeDir = baritone.getDirectory(); + } + + return Optional.of(new Tuple<>(worldDir, readmeDir)); + } + + /** + * Why does this exist instead of fixing the event? Some mods break the event. Lol. + */ + private void detectAndHandleBrokenLoading() { + if (this.mcWorld != ctx.world()) { if (this.currentWorld != null) { System.out.println("mc.world unloaded unnoticed! Unloading Baritone cache now."); closeWorld(); } - if (mc.world != null) { + if (ctx.world() != null) { System.out.println("mc.world loaded unnoticed! Loading Baritone cache now."); - initWorld(mc.world.provider.getDimensionType().getId()); + initWorld(ctx.world()); } - } else if (currentWorld == null && mc.world != null && (mc.isSingleplayer() || mc.getCurrentServerData() != null)) { + } else if (this.currentWorld == null && ctx.world() != null && (ctx.minecraft().isSingleplayer() || ctx.minecraft().getCurrentServerData() != null)) { System.out.println("Retrying to load Baritone cache"); - initWorld(mc.world.provider.getDimensionType().getId()); + initWorld(ctx.world()); } } } diff --git a/src/main/java/baritone/command/ExampleBaritoneControl.java b/src/main/java/baritone/command/ExampleBaritoneControl.java index 28ced07f4..1a7b69644 100644 --- a/src/main/java/baritone/command/ExampleBaritoneControl.java +++ b/src/main/java/baritone/command/ExampleBaritoneControl.java @@ -17,8 +17,8 @@ package baritone.command; +import baritone.Baritone; import baritone.api.BaritoneAPI; -import baritone.api.IBaritone; import baritone.api.Settings; import baritone.api.command.argument.ICommandArgument; import baritone.api.command.exception.CommandNotEnoughArgumentsException; @@ -30,6 +30,7 @@ import baritone.api.event.events.TabCompleteEvent; import baritone.api.event.listener.AbstractGameEventListener; import baritone.api.utils.Helper; import baritone.api.utils.SettingsUtil; +import baritone.behavior.Behavior; import baritone.command.argument.ArgConsumer; import baritone.command.argument.CommandArguments; import baritone.command.manager.CommandManager; @@ -49,14 +50,14 @@ import java.util.stream.Stream; import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX; -public class ExampleBaritoneControl implements Helper, AbstractGameEventListener { +public class ExampleBaritoneControl extends Behavior implements Helper { private static final Settings settings = BaritoneAPI.getSettings(); private final ICommandManager manager; - public ExampleBaritoneControl(IBaritone baritone) { + public ExampleBaritoneControl(Baritone baritone) { + super(baritone); this.manager = baritone.getCommandManager(); - baritone.getGameEventHandler().registerEventListener(this); } @Override @@ -100,7 +101,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener return false; } else if (msg.trim().equalsIgnoreCase("orderpizza")) { try { - ((IGuiScreen) mc.currentScreen).openLink(new URI("https://www.dominos.com/en/pages/order/")); + ((IGuiScreen) ctx.minecraft().currentScreen).openLink(new URI("https://www.dominos.com/en/pages/order/")); } catch (NullPointerException | URISyntaxException ignored) {} return false; } diff --git a/src/main/java/baritone/command/defaults/BuildCommand.java b/src/main/java/baritone/command/defaults/BuildCommand.java index 724582865..12f287955 100644 --- a/src/main/java/baritone/command/defaults/BuildCommand.java +++ b/src/main/java/baritone/command/defaults/BuildCommand.java @@ -26,7 +26,6 @@ import baritone.api.command.datatypes.RelativeFile; import baritone.api.command.exception.CommandException; import baritone.api.command.exception.CommandInvalidStateException; import baritone.api.utils.BetterBlockPos; -import net.minecraft.client.Minecraft; import org.apache.commons.io.FilenameUtils; import java.io.File; @@ -36,10 +35,11 @@ import java.util.stream.Stream; public class BuildCommand extends Command { - private static final File schematicsDir = new File(Minecraft.getMinecraft().gameDir, "schematics"); + private final File schematicsDir; public BuildCommand(IBaritone baritone) { super(baritone, "build"); + this.schematicsDir = new File(baritone.getPlayerContext().minecraft().gameDir, "schematics"); } @Override diff --git a/src/main/java/baritone/command/defaults/ComeCommand.java b/src/main/java/baritone/command/defaults/ComeCommand.java index 5d3e3b829..b111ee1de 100644 --- a/src/main/java/baritone/command/defaults/ComeCommand.java +++ b/src/main/java/baritone/command/defaults/ComeCommand.java @@ -21,10 +21,7 @@ import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; import baritone.api.command.exception.CommandException; -import baritone.api.command.exception.CommandInvalidStateException; import baritone.api.pathing.goals.GoalBlock; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.BlockPos; import java.util.Arrays; import java.util.List; @@ -39,11 +36,7 @@ public class ComeCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { args.requireMax(0); - Entity entity = mc.getRenderViewEntity(); - if (entity == null) { - throw new CommandInvalidStateException("render view entity is null"); - } - baritone.getCustomGoalProcess().setGoalAndPath(new GoalBlock(new BlockPos(entity))); + baritone.getCustomGoalProcess().setGoalAndPath(new GoalBlock(ctx.viewerPos())); logDirect("Coming"); } diff --git a/src/main/java/baritone/command/defaults/ExploreFilterCommand.java b/src/main/java/baritone/command/defaults/ExploreFilterCommand.java index c2057551f..6f306a966 100644 --- a/src/main/java/baritone/command/defaults/ExploreFilterCommand.java +++ b/src/main/java/baritone/command/defaults/ExploreFilterCommand.java @@ -41,7 +41,7 @@ public class ExploreFilterCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { args.requireMax(2); - File file = args.getDatatypePost(RelativeFile.INSTANCE, mc.gameDir.getAbsoluteFile().getParentFile()); + File file = args.getDatatypePost(RelativeFile.INSTANCE, ctx.minecraft().gameDir.getAbsoluteFile().getParentFile()); boolean invert = false; if (args.hasAny()) { if (args.getString().equalsIgnoreCase("invert")) { @@ -65,7 +65,7 @@ public class ExploreFilterCommand extends Command { @Override public Stream tabComplete(String label, IArgConsumer args) throws CommandException { if (args.hasExactlyOne()) { - return RelativeFile.tabComplete(args, RelativeFile.gameDir()); + return RelativeFile.tabComplete(args, RelativeFile.gameDir(ctx.minecraft())); } return Stream.empty(); } diff --git a/src/main/java/baritone/command/defaults/RenderCommand.java b/src/main/java/baritone/command/defaults/RenderCommand.java index cc9803d16..ab4a9dbcd 100644 --- a/src/main/java/baritone/command/defaults/RenderCommand.java +++ b/src/main/java/baritone/command/defaults/RenderCommand.java @@ -37,8 +37,8 @@ public class RenderCommand extends Command { public void execute(String label, IArgConsumer args) throws CommandException { args.requireMax(0); BetterBlockPos origin = ctx.playerFeet(); - int renderDistance = (mc.gameSettings.renderDistanceChunks + 1) * 16; - mc.renderGlobal.markBlockRangeForRenderUpdate( + int renderDistance = (ctx.minecraft().gameSettings.renderDistanceChunks + 1) * 16; + ctx.minecraft().renderGlobal.markBlockRangeForRenderUpdate( origin.x - renderDistance, 0, origin.z - renderDistance, diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java index 9abe417ac..78035aa4e 100644 --- a/src/main/java/baritone/command/defaults/SelCommand.java +++ b/src/main/java/baritone/command/defaults/SelCommand.java @@ -92,7 +92,7 @@ public class SelCommand extends Command { if (action == Action.POS2 && pos1 == null) { throw new CommandInvalidStateException("Set pos1 first before using pos2"); } - BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet(); + BetterBlockPos playerPos = ctx.viewerPos(); BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos; args.requireMax(0); if (action == Action.POS1) { @@ -198,7 +198,7 @@ public class SelCommand extends Command { baritone.getBuilderProcess().build("Fill", composite, origin); logDirect("Filling now"); } else if (action == Action.COPY) { - BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet(); + BetterBlockPos playerPos = ctx.viewerPos(); BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos; args.requireMax(0); ISelection[] selections = manager.getSelections(); @@ -239,7 +239,7 @@ public class SelCommand extends Command { clipboardOffset = origin.subtract(pos); logDirect("Selection copied"); } else if (action == Action.PASTE) { - BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet(); + BetterBlockPos playerPos = ctx.viewerPos(); BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos; args.requireMax(0); if (clipboard == null) { diff --git a/src/main/java/baritone/command/defaults/SurfaceCommand.java b/src/main/java/baritone/command/defaults/SurfaceCommand.java index 5d914aded..9ab22bdc2 100644 --- a/src/main/java/baritone/command/defaults/SurfaceCommand.java +++ b/src/main/java/baritone/command/defaults/SurfaceCommand.java @@ -54,7 +54,7 @@ public class SurfaceCommand extends Command { for (int currentIteratedY = startingYPos; currentIteratedY < worldHeight; currentIteratedY++) { final BetterBlockPos newPos = new BetterBlockPos(playerPos.getX(), currentIteratedY, playerPos.getZ()); - if (!(mc.world.getBlockState(newPos).getBlock() instanceof BlockAir) && newPos.getY() > playerPos.getY()) { + if (!(ctx.world().getBlockState(newPos).getBlock() instanceof BlockAir) && newPos.getY() > playerPos.getY()) { Goal goal = new GoalBlock(newPos.up()); logDirect(String.format("Going to: %s", goal.toString())); baritone.getCustomGoalProcess().setGoalAndPath(goal); diff --git a/src/main/java/baritone/event/GameEventHandler.java b/src/main/java/baritone/event/GameEventHandler.java index 8916f7f37..0b46eb5e1 100644 --- a/src/main/java/baritone/event/GameEventHandler.java +++ b/src/main/java/baritone/event/GameEventHandler.java @@ -114,7 +114,7 @@ public final class GameEventHandler implements IEventBus, Helper { if (event.getState() == EventState.POST) { cache.closeWorld(); if (event.getWorld() != null) { - cache.initWorld(event.getWorld().provider.getDimensionType().getId()); + cache.initWorld(event.getWorld()); } } diff --git a/src/main/java/baritone/pathing/movement/CalculationContext.java b/src/main/java/baritone/pathing/movement/CalculationContext.java index 177435ef1..129f00e20 100644 --- a/src/main/java/baritone/pathing/movement/CalculationContext.java +++ b/src/main/java/baritone/pathing/movement/CalculationContext.java @@ -91,8 +91,8 @@ public class CalculationContext { this.baritone = baritone; EntityPlayerSP player = baritone.getPlayerContext().player(); this.world = baritone.getPlayerContext().world(); - this.worldData = (WorldData) baritone.getWorldProvider().getCurrentWorld(); - this.bsi = new BlockStateInterface(world, worldData, forUseOnAnotherThread); + this.worldData = (WorldData) baritone.getPlayerContext().worldData(); + this.bsi = new BlockStateInterface(baritone.getPlayerContext(), forUseOnAnotherThread); this.toolSet = new ToolSet(player); this.hasThrowaway = Baritone.settings().allowPlace.value && ((Baritone) baritone).getInventoryBehavior().hasGenericThrowaway(); this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.value && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.provider.isNether(); diff --git a/src/main/java/baritone/utils/BlockBreakHelper.java b/src/main/java/baritone/utils/BlockBreakHelper.java index 26e82cd78..c4ed11f0c 100644 --- a/src/main/java/baritone/utils/BlockBreakHelper.java +++ b/src/main/java/baritone/utils/BlockBreakHelper.java @@ -17,7 +17,6 @@ package baritone.utils; -import baritone.api.utils.Helper; import baritone.api.utils.IPlayerContext; import net.minecraft.util.EnumHand; import net.minecraft.util.math.RayTraceResult; @@ -26,7 +25,7 @@ import net.minecraft.util.math.RayTraceResult; * @author Brady * @since 8/25/2018 */ -public final class BlockBreakHelper implements Helper { +public final class BlockBreakHelper { private final IPlayerContext ctx; private boolean didBreakLastTick; diff --git a/src/main/java/baritone/utils/BlockPlaceHelper.java b/src/main/java/baritone/utils/BlockPlaceHelper.java index 440bfb93d..69dea61b8 100644 --- a/src/main/java/baritone/utils/BlockPlaceHelper.java +++ b/src/main/java/baritone/utils/BlockPlaceHelper.java @@ -18,13 +18,12 @@ package baritone.utils; import baritone.Baritone; -import baritone.api.utils.Helper; import baritone.api.utils.IPlayerContext; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumHand; import net.minecraft.util.math.RayTraceResult; -public class BlockPlaceHelper implements Helper { +public class BlockPlaceHelper { private final IPlayerContext ctx; private int rightClickTimer; diff --git a/src/main/java/baritone/utils/BlockStateInterface.java b/src/main/java/baritone/utils/BlockStateInterface.java index f451c2f1d..1d6dcaf79 100644 --- a/src/main/java/baritone/utils/BlockStateInterface.java +++ b/src/main/java/baritone/utils/BlockStateInterface.java @@ -27,7 +27,6 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; @@ -44,7 +43,6 @@ public class BlockStateInterface { private final Long2ObjectMap loadedChunks; private final WorldData worldData; - protected final IBlockAccess world; public final BlockPos.MutableBlockPos isPassableBlockPos; public final IBlockAccess access; public final BetterWorldBorder worldBorder; @@ -61,13 +59,9 @@ public class BlockStateInterface { } public BlockStateInterface(IPlayerContext ctx, boolean copyLoadedChunks) { - this(ctx.world(), (WorldData) ctx.worldData(), copyLoadedChunks); - } - - public BlockStateInterface(World world, WorldData worldData, boolean copyLoadedChunks) { - this.world = world; + final World world = ctx.world(); this.worldBorder = new BetterWorldBorder(world.getWorldBorder()); - this.worldData = worldData; + this.worldData = (WorldData) ctx.worldData(); Long2ObjectMap worldLoaded = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks(); if (copyLoadedChunks) { this.loadedChunks = new Long2ObjectOpenHashMap<>(worldLoaded); // make a copy that we can safely access from another thread @@ -75,11 +69,11 @@ public class BlockStateInterface { this.loadedChunks = worldLoaded; // this will only be used on the main thread } this.useTheRealWorld = !Baritone.settings().pathThroughCachedOnly.value; - if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) { + if (!ctx.minecraft().isCallingFromMinecraftThread()) { throw new IllegalStateException(); } this.isPassableBlockPos = new BlockPos.MutableBlockPos(); - this.access = new BlockStateInterfaceAccessWrapper(this); + this.access = new BlockStateInterfaceAccessWrapper(this, world); } public boolean worldContainsLoadedChunk(int blockX, int blockZ) { diff --git a/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java b/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java index 6dded1dd5..7ebde5f23 100644 --- a/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java +++ b/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java @@ -37,9 +37,11 @@ import javax.annotation.Nullable; public final class BlockStateInterfaceAccessWrapper implements IBlockAccess { private final BlockStateInterface bsi; + private final IBlockAccess world; - BlockStateInterfaceAccessWrapper(BlockStateInterface bsi) { + BlockStateInterfaceAccessWrapper(BlockStateInterface bsi, IBlockAccess world) { this.bsi = bsi; + this.world = world; } @Nullable @@ -76,6 +78,6 @@ public final class BlockStateInterfaceAccessWrapper implements IBlockAccess { @Override public WorldType getWorldType() { - return this.bsi.world.getWorldType(); + return this.world.getWorldType(); } } diff --git a/src/main/java/baritone/utils/IRenderer.java b/src/main/java/baritone/utils/IRenderer.java index 26a7cf1ad..2134bcb99 100644 --- a/src/main/java/baritone/utils/IRenderer.java +++ b/src/main/java/baritone/utils/IRenderer.java @@ -19,11 +19,12 @@ package baritone.utils; import baritone.api.BaritoneAPI; import baritone.api.Settings; -import baritone.api.utils.Helper; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; 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; @@ -35,7 +36,8 @@ public interface IRenderer { Tessellator tessellator = Tessellator.getInstance(); BufferBuilder buffer = tessellator.getBuffer(); - RenderManager renderManager = Helper.mc.getRenderManager(); + RenderManager renderManager = Minecraft.getMinecraft().getRenderManager(); + TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); Settings settings = BaritoneAPI.getSettings(); float[] color = new float[] {1.0F, 1.0F, 1.0F, 255.0F}; diff --git a/src/main/java/baritone/utils/InputOverrideHandler.java b/src/main/java/baritone/utils/InputOverrideHandler.java index d1c4689a2..f110b9ce1 100755 --- a/src/main/java/baritone/utils/InputOverrideHandler.java +++ b/src/main/java/baritone/utils/InputOverrideHandler.java @@ -23,7 +23,6 @@ import baritone.api.event.events.TickEvent; import baritone.api.utils.IInputOverrideHandler; import baritone.api.utils.input.Input; import baritone.behavior.Behavior; -import net.minecraft.client.Minecraft; import net.minecraft.util.MovementInputFromOptions; import java.util.HashMap; @@ -100,7 +99,7 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri } } else { if (ctx.player().movementInput.getClass() == PlayerMovementInput.class) { // allow other movement inputs that aren't this one, e.g. for a freecam - ctx.player().movementInput = new MovementInputFromOptions(Minecraft.getMinecraft().gameSettings); + ctx.player().movementInput = new MovementInputFromOptions(ctx.minecraft().gameSettings); } } // only set it if it was previously incorrect diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index deec261d4..65bf6269c 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -22,7 +22,7 @@ import baritone.api.event.events.RenderEvent; import baritone.api.pathing.calc.IPath; import baritone.api.pathing.goals.*; import baritone.api.utils.BetterBlockPos; -import baritone.api.utils.Helper; +import baritone.api.utils.IPlayerContext; import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.behavior.PathingBehavior; import baritone.pathing.path.PathExecutor; @@ -52,31 +52,40 @@ public final class PathRenderer implements IRenderer { private PathRenderer() {} public static void render(RenderEvent event, PathingBehavior behavior) { - float partialTicks = event.getPartialTicks(); - Goal goal = behavior.getGoal(); - if (Helper.mc.currentScreen instanceof GuiClick) { - ((GuiClick) Helper.mc.currentScreen).onRender(); + final IPlayerContext ctx = behavior.ctx; + if (ctx.world() == null) { + return; + } + if (ctx.minecraft().currentScreen instanceof GuiClick) { + ((GuiClick) ctx.minecraft().currentScreen).onRender(); } - int thisPlayerDimension = behavior.baritone.getPlayerContext().world().provider.getDimensionType().getId(); - int currentRenderViewDimension = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world().provider.getDimensionType().getId(); + final float partialTicks = event.getPartialTicks(); + final Goal goal = behavior.getGoal(); + + final int thisPlayerDimension = ctx.world().provider.getDimensionType().getId(); + final int currentRenderViewDimension = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world().provider.getDimensionType().getId(); if (thisPlayerDimension != currentRenderViewDimension) { // this is a path for a bot in a different dimension, don't render it return; } - Entity renderView = Helper.mc.getRenderViewEntity(); - - if (renderView.world != BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world()) { - System.out.println("I have no idea what's going on"); - System.out.println("The primary baritone is in a different world than the render view entity"); - System.out.println("Not rendering the path"); - return; - } + // TODO: This is goofy 💀 (pr/deprecateHelperMc) + // renderView isn't even needed for drawGoal since it's only used to + // calculate GoalYLevel x/z bounds, and ends up just cancelling itself + // out because of viewerPosX/Y/Z. I just changed it to center around the + // actual player so the goal box doesn't follow the camera in freecam. +// Entity renderView = Helper.mc.getRenderViewEntity(); +// if (renderView.world != BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world()) { +// System.out.println("I have no idea what's going on"); +// System.out.println("The primary baritone is in a different world than the render view entity"); +// System.out.println("Not rendering the path"); +// return; +// } if (goal != null && settings.renderGoal.value) { - drawGoal(renderView, goal, partialTicks, settings.colorGoalBox.value); + drawGoal(ctx.player(), goal, partialTicks, settings.colorGoalBox.value); } if (!settings.renderPath.value) { @@ -86,9 +95,9 @@ public final class PathRenderer implements IRenderer { PathExecutor current = behavior.getCurrent(); // this should prevent most race conditions? PathExecutor next = behavior.getNext(); // like, now it's not possible for current!=null to be true, then suddenly false because of another thread if (current != null && settings.renderSelectionBoxes.value) { - drawManySelectionBoxes(renderView, current.toBreak(), settings.colorBlocksToBreak.value); - drawManySelectionBoxes(renderView, current.toPlace(), settings.colorBlocksToPlace.value); - drawManySelectionBoxes(renderView, current.toWalkInto(), settings.colorBlocksToWalkInto.value); + drawManySelectionBoxes(ctx.player(), current.toBreak(), settings.colorBlocksToBreak.value); + drawManySelectionBoxes(ctx.player(), current.toPlace(), settings.colorBlocksToPlace.value); + drawManySelectionBoxes(ctx.player(), current.toWalkInto(), settings.colorBlocksToWalkInto.value); } //drawManySelectionBoxes(player, Collections.singletonList(behavior.pathStart()), partialTicks, Color.WHITE); @@ -111,12 +120,12 @@ public final class PathRenderer implements IRenderer { currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> { drawPath(mr, 0, settings.colorMostRecentConsidered.value, settings.fadePath.value, 10, 20); - drawManySelectionBoxes(renderView, Collections.singletonList(mr.getDest()), settings.colorMostRecentConsidered.value); + drawManySelectionBoxes(ctx.player(), Collections.singletonList(mr.getDest()), settings.colorMostRecentConsidered.value); }); }); } - public static void drawPath(IPath path, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { + private static void drawPath(IPath path, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); int fadeStart = fadeStart0 + startIndex; @@ -159,7 +168,7 @@ public final class PathRenderer implements IRenderer { IRenderer.endLines(settings.renderPathIgnoreDepth.value); } - public static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { + 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; @@ -202,11 +211,11 @@ public final class PathRenderer implements IRenderer { IRenderer.endLines(settings.renderSelectionBoxesIgnoreDepth.value); } - public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) { + private static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) { drawGoal(player, goal, partialTicks, color, true); } - public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color, boolean setupRender) { + private static void drawGoal(Entity player, Goal goal, float partialTicks, Color color, boolean setupRender) { double renderPosX = renderManager.viewerPosX; double renderPosY = renderManager.viewerPosY; double renderPosZ = renderManager.viewerPosZ; @@ -245,7 +254,7 @@ public final class PathRenderer implements IRenderer { if (settings.renderGoalXZBeacon.value) { glPushAttrib(GL_LIGHTING_BIT); - Helper.mc.getTextureManager().bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM); + textureManager.bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM); if (settings.renderGoalIgnoreDepth.value) { GlStateManager.disableDepth(); diff --git a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java b/src/main/java/baritone/utils/player/BaritonePlayerContext.java similarity index 58% rename from src/main/java/baritone/utils/player/PrimaryPlayerContext.java rename to src/main/java/baritone/utils/player/BaritonePlayerContext.java index 02db73a5c..282d3d8b6 100644 --- a/src/main/java/baritone/utils/player/PrimaryPlayerContext.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerContext.java @@ -17,11 +17,13 @@ package baritone.utils.player; -import baritone.api.BaritoneAPI; +import baritone.Baritone; import baritone.api.cache.IWorldData; import baritone.api.utils.*; -import baritone.behavior.LookBehavior; +import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; @@ -31,34 +33,52 @@ import net.minecraft.world.World; * @author Brady * @since 11/12/2018 */ -public enum PrimaryPlayerContext implements IPlayerContext, Helper { +public final class BaritonePlayerContext implements IPlayerContext { - INSTANCE; + private final Baritone baritone; + private final Minecraft mc; + private final IPlayerController playerController; + + public BaritonePlayerContext(Baritone baritone, Minecraft mc) { + this.baritone = baritone; + this.mc = mc; + this.playerController = new BaritonePlayerController(mc); + } + + @Override + public Minecraft minecraft() { + return this.mc; + } @Override public EntityPlayerSP player() { - return mc.player; + return this.mc.player; } @Override public IPlayerController playerController() { - return PrimaryPlayerController.INSTANCE; + return this.playerController; } @Override public World world() { - return mc.world; + return this.mc.world; } @Override public IWorldData worldData() { - return BaritoneAPI.getProvider().getPrimaryBaritone().getWorldProvider().getCurrentWorld(); + return this.baritone.getWorldProvider().getCurrentWorld(); + } + + @Override + public BetterBlockPos viewerPos() { + final Entity entity = this.mc.getRenderViewEntity(); + return entity == null ? this.playerFeet() : BetterBlockPos.from(new BlockPos(entity)); } @Override public Rotation playerRotations() { - return ((LookBehavior) BaritoneAPI.getProvider().getPrimaryBaritone().getLookBehavior()).getEffectiveRotation() - .orElseGet(IPlayerContext.super::playerRotations); + return this.baritone.getLookBehavior().getEffectiveRotation().orElseGet(IPlayerContext.super::playerRotations); } @Override diff --git a/src/main/java/baritone/utils/player/PrimaryPlayerController.java b/src/main/java/baritone/utils/player/BaritonePlayerController.java similarity index 93% rename from src/main/java/baritone/utils/player/PrimaryPlayerController.java rename to src/main/java/baritone/utils/player/BaritonePlayerController.java index b013f9161..694ffab6c 100644 --- a/src/main/java/baritone/utils/player/PrimaryPlayerController.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerController.java @@ -17,9 +17,9 @@ package baritone.utils.player; -import baritone.api.utils.Helper; import baritone.api.utils.IPlayerController; import baritone.utils.accessor.IPlayerControllerMP; +import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.entity.player.EntityPlayer; @@ -39,9 +39,13 @@ import net.minecraft.world.World; * @author Brady * @since 12/14/2018 */ -public enum PrimaryPlayerController implements IPlayerController, Helper { +public final class BaritonePlayerController implements IPlayerController { - INSTANCE; + private final Minecraft mc; + + public BaritonePlayerController(Minecraft mc) { + this.mc = mc; + } @Override public void syncHeldItem() {