First version of selection stuff; nothing supports it yet

This commit is contained in:
Logan Darklock 2019-09-02 11:29:48 -07:00
parent 98bb3fba9c
commit bc0f2b59da
No known key found for this signature in database
GPG Key ID: B8C37CEDE1AC60EA
14 changed files with 800 additions and 188 deletions

View File

@ -23,6 +23,7 @@ import baritone.api.cache.IWorldProvider;
import baritone.api.event.listener.IEventBus;
import baritone.api.pathing.calc.IPathingControlManager;
import baritone.api.process.*;
import baritone.api.selection.ISelectionManager;
import baritone.api.utils.IInputOverrideHandler;
import baritone.api.utils.IPlayerContext;
@ -128,6 +129,12 @@ public interface IBaritone {
*/
IEventBus getGameEventHandler();
/**
* @return The {@link ISelectionManager} instance
* @see ISelectionManager
*/
ISelectionManager getSelectionManager();
/**
* Open click
*/

View File

@ -528,6 +528,21 @@ public final class Settings {
*/
public final Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
/**
* Ignore depth when rendering selections
*/
public final Setting<Boolean> renderSelectionIgnoreDepth = new Setting<>(true);
/**
* Render selections
*/
public final Setting<Boolean> renderSelection = new Setting<>(true);
/**
* Render selection corners
*/
public final Setting<Boolean> renderSelectionCorners = new Setting<>(true);
/**
* Line width of the path when rendered, in pixels
*/
@ -538,6 +553,11 @@ public final class Settings {
*/
public final Setting<Float> goalRenderLineWidthPixels = new Setting<>(3F);
/**
* Line width of the goal when rendered, in pixels
*/
public final Setting<Float> selectionRenderLineWidthPixels = new Setting<>(3F);
/**
* Start fading out the path at 20 movements ahead, and stop rendering it entirely 30 movements ahead.
* Improves FPS.
@ -935,6 +955,21 @@ public final class Settings {
*/
public final Setting<Color> colorInvertedGoalBox = new Setting<>(Color.RED);
/**
* The color of all selections
*/
public final Setting<Color> colorSelection = new Setting<>(Color.GREEN);
/**
* The color of the selection pos 1
*/
public final Setting<Color> colorSelectionPos1 = new Setting<>(Color.PINK);
/**
* The color of the selection pos 2
*/
public final Setting<Color> colorSelectionPos2 = new Setting<>(Color.PINK);
/**
* A map of lowercase setting field names to their respective setting

View File

@ -0,0 +1,73 @@
package baritone.api.selection;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3i;
/**
* A selection is an immutable object representing the current selection. The selection is commonly used for certain
* types of build commands, however it can be used for anything.
*/
public interface ISelection {
/**
* @return The first corner of this selection. This is meant to preserve the user's original first corner.
*/
BetterBlockPos pos1();
/**
* @return The second corner of this selection. This is meant to preserve the user's original second corner.
*/
BetterBlockPos pos2();
/**
* @return The {@link BetterBlockPos} with the lowest x, y, and z position in the selection.
*/
BetterBlockPos min();
/**
* @return The opposite corner from the {@link #min()}.
*/
BetterBlockPos max();
/**
* @return The size of this ISelection.
*/
Vec3i size();
/**
* @return An {@link AxisAlignedBB} encompassing all blocks in this selection.
*/
AxisAlignedBB aabb();
/**
* Returns a new {@link ISelection} expanded in the specified direction by the specified number of blocks.
*
* @param direction The direction to expand the selection.
* @param blocks How many blocks to expand it.
* @return A new selection, expanded as specified.
*/
ISelection expand(EnumFacing direction, int blocks);
/**
* Returns a new {@link ISelection} contracted in the specified direction by the specified number of blocks.
*
* Note that, for example, if the direction specified is UP, the bottom of the selection will be shifted up. If it
* is DOWN, the top of the selection will be shifted down.
*
* @param direction The direction to contract the selection.
* @param blocks How many blocks to contract it.
* @return A new selection, contracted as specified.
*/
ISelection contract(EnumFacing direction, int blocks);
/**
* Returns a new {@link ISelection} shifted in the specified direction by the specified number of blocks. This moves
* the whole selection.
*
* @param direction The direction to shift the selection.
* @param blocks How many blocks to shift it.
* @return A new selection, shifted as specified.
*/
ISelection shift(EnumFacing direction, int blocks);
}

View File

@ -0,0 +1,52 @@
package baritone.api.selection;
import baritone.api.utils.BetterBlockPos;
/**
* The selection manager handles setting Baritone's selections. You can set the selection here, as well as retrieving
* the current selection.
*/
public interface ISelectionManager {
/**
* Adds a new selection. The added selection is returned.
*
* @param selection The new selection to add.
*/
ISelection addSelection(ISelection selection);
/**
* Adds a new {@link ISelection} constructed from the given block positions. The new selection is returned.
*
* @param pos1 One corner of the selection
* @param pos2 The new corner of the selection
*/
ISelection addSelection(BetterBlockPos pos1, BetterBlockPos pos2);
/**
* Removes the selection from the current selections.
*
* @param selection The selection to remove.
* @return The removed selection.
*/
ISelection removeSelection(ISelection selection);
/**
* Removes all selections.
*
* @return The selections that were removed, sorted from oldest to newest..
*/
ISelection[] removeAllSelections();
/**
* @return The current selections, sorted from oldest to newest.
*/
ISelection[] getSelections();
/**
* For anything expecting only one selection, this method is provided. However, to enforce multi-selection support,
* this method will only return a selection if there is ONLY one.
*
* @return The only selection.
*/
ISelection getOnlySelection();
}

View File

@ -0,0 +1,88 @@
package baritone.api.utils;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
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.vertex.DefaultVertexFormats;
import net.minecraft.util.math.AxisAlignedBB;
import java.awt.Color;
import static org.lwjgl.opengl.GL11.GL_LINES;
import static org.lwjgl.opengl.GL11.GL_ONE;
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_ZERO;
public interface IRenderer {
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
IBaritone baritone = BaritoneAPI.getProvider().getPrimaryBaritone();
Settings settings = BaritoneAPI.getSettings();
static void startLines(Color color, float lineWidth, boolean ignoreDepth) {
GlStateManager.enableBlend();
GlStateManager.disableLighting();
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
float[] colorComponents = color.getColorComponents(null);
GlStateManager.color(colorComponents[0], colorComponents[1], colorComponents[2], 0.4f);
GlStateManager.glLineWidth(lineWidth);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (ignoreDepth) {
GlStateManager.disableDepth();
}
}
static void endLines(boolean ignoredDepth) {
if (ignoredDepth) {
GlStateManager.enableDepth();
}
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.enableLighting();
GlStateManager.disableBlend();
}
static void drawAABB(AxisAlignedBB aabb) {
float expand = 0.002F;
RenderManager renderManager = Helper.mc.getRenderManager();
AxisAlignedBB toDraw = aabb.expand(expand, expand, expand).offset(-renderManager.viewerPosX, -renderManager.viewerPosY, -renderManager.viewerPosZ);
buffer.begin(GL_LINES, DefaultVertexFormats.POSITION);
// bottom
buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
// top
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
// corners
buffer.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
buffer.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
tessellator.draw();
}
}

View File

@ -20,6 +20,7 @@ package baritone.api.utils.command;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.command.execution.CommandExecution;
@ -34,8 +35,9 @@ import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public abstract class Command implements Helper {
public abstract class Command implements Helper, AbstractGameEventListener {
protected IBaritone baritone = BaritoneAPI.getProvider().getPrimaryBaritone();
protected Settings settings = BaritoneAPI.getSettings();
protected IPlayerContext ctx = baritone.getPlayerContext();
protected Minecraft MC = mc;
@ -60,6 +62,7 @@ public abstract class Command implements Helper {
.map(s -> s.toLowerCase(Locale.US))
.collect(Collectors.toCollection(ArrayList::new));
this.shortDesc = shortDesc;
baritone.getGameEventHandler().registerEventListener(this);
}
protected Command(String name, String shortDesc) {

View File

@ -64,6 +64,7 @@ public class DefaultCommands {
new ThisWayCommand(),
new WaypointsCommand(),
new CommandAlias("sethome", "Sets your home waypoint", "waypoints save home"),
new CommandAlias("home", "Set goal to your home waypoint", "waypoints goal home")
new CommandAlias("home", "Set goal to your home waypoint", "waypoints goal home"),
new SelCommand()
));
}

View File

@ -0,0 +1,160 @@
/*
* 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.utils.command.defaults;
import baritone.api.Settings;
import baritone.api.event.events.RenderEvent;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.IRenderer;
import baritone.api.utils.command.Command;
import baritone.api.utils.command.datatypes.RelativeBlockPos;
import baritone.api.utils.command.exception.CommandInvalidStateException;
import baritone.api.utils.command.exception.CommandInvalidTypeException;
import baritone.api.utils.command.helpers.arguments.ArgConsumer;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import net.minecraft.util.math.AxisAlignedBB;
import java.awt.Color;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class SelCommand extends Command {
private BetterBlockPos pos1 = null;
public SelCommand() {
super(asList("sel", "selection", "s"), "WorldEdit-like commands");
}
@Override
protected void executed(String label, ArgConsumer args, Settings settings) {
Action action = Action.getByName(args.getString());
if (action == null) {
throw new CommandInvalidTypeException(args.consumed(), "an action");
}
if (action == Action.POS1 || action == Action.POS2) {
if (action == Action.POS2 && pos1 == null) {
throw new CommandInvalidStateException("Set pos1 first before using pos2");
}
BetterBlockPos playerPos = ctx.playerFeet();
BetterBlockPos pos = args.has() ? args.getDatatypePost(RelativeBlockPos.class, playerPos) : playerPos;
args.requireMax(0);
if (action == Action.POS1) {
pos1 = pos;
logDirect("Position 1 has been set");
} else {
baritone.getSelectionManager().addSelection(pos1, pos);
pos1 = null;
logDirect("Selection added");
}
} else if (action == Action.CLEAR) {
pos1 = null;
logDirect(String.format(
"Removed %d selections",
baritone.getSelectionManager().removeAllSelections().length
));
}
}
@Override
protected Stream<String> tabCompleted(String label, ArgConsumer args, Settings settings) {
if (args.hasExactlyOne()) {
return new TabCompleteHelper()
.append(Action.getAllNames())
.filterPrefix(args.getString())
.sortAlphabetically()
.stream();
} else {
Action action = Action.getByName(args.getString());
if (action != null) {
if (action == Action.POS1 || action == Action.POS2) {
return args.tabCompleteDatatype(RelativeBlockPos.class);
}
}
}
return Stream.empty();
}
@Override
public List<String> getLongDesc() {
return asList(
"",
"",
"Usage:",
"> "
);
}
enum Action {
POS1("pos1", "p1"),
POS2("pos2", "p2"),
CLEAR("clear", "c");
private final String[] names;
Action(String... names) {
this.names = names;
}
public static Action getByName(String name) {
for (Action action : Action.values()) {
for (String alias : action.names) {
if (alias.equalsIgnoreCase(name)) {
return action;
}
}
}
return null;
}
public static String[] getAllNames() {
Set<String> names = new HashSet<>();
for (Action action : Action.values()) {
names.addAll(asList(action.names));
}
return names.toArray(new String[0]);
}
}
@Override
public void onRenderPass(RenderEvent event) {
if (!settings.renderSelectionCorners.value || pos1 == null) {
return;
}
Color color = settings.colorSelectionPos1.value;
float lineWidth = settings.selectionRenderLineWidthPixels.value;
boolean ignoreDepth = settings.renderSelectionIgnoreDepth.value;
IRenderer.startLines(color, lineWidth, ignoreDepth);
IRenderer.drawAABB(new AxisAlignedBB(pos1, pos1.add(1, 1, 1)));
IRenderer.endLines(ignoreDepth);
}
}

View File

@ -28,6 +28,7 @@ import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.event.GameEventHandler;
import baritone.process.*;
import baritone.selection.SelectionManager;
import baritone.utils.*;
import baritone.utils.player.PrimaryPlayerContext;
import net.minecraft.client.Minecraft;
@ -83,6 +84,7 @@ public class Baritone implements IBaritone {
private FarmProcess farmProcess;
private PathingControlManager pathingControlManager;
private SelectionManager selectionManager;
private IPlayerContext playerContext;
private WorldProvider worldProvider;
@ -125,6 +127,7 @@ public class Baritone implements IBaritone {
}
this.worldProvider = new WorldProvider();
this.selectionManager = new SelectionManager();
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
this.gameEventHandler.registerEventListener(BaritoneAutoTest.INSTANCE);
@ -203,6 +206,11 @@ public class Baritone implements IBaritone {
return this.pathingBehavior;
}
@Override
public SelectionManager getSelectionManager() {
return selectionManager;
}
@Override
public WorldProvider getWorldProvider() {
return this.worldProvider;

View File

@ -0,0 +1,129 @@
package baritone.selection;
import baritone.api.selection.ISelection;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3i;
public class Selection implements ISelection {
private final BetterBlockPos pos1;
private final BetterBlockPos pos2;
private final BetterBlockPos min;
private final BetterBlockPos max;
private final Vec3i size;
private final AxisAlignedBB aabb;
public Selection(BetterBlockPos pos1, BetterBlockPos pos2) {
this.pos1 = pos1;
this.pos2 = pos2;
this.min = new BetterBlockPos(
Math.min(pos1.x, pos2.x),
Math.min(pos1.y, pos2.y),
Math.min(pos1.z, pos2.z)
);
this.max = new BetterBlockPos(
Math.max(pos1.x, pos2.x),
Math.max(pos1.y, pos2.y),
Math.max(pos1.z, pos2.z)
);
this.size = new Vec3i(
max.x - min.x + 1,
max.y - min.y + 1,
max.z - min.z + 1
);
this.aabb = new AxisAlignedBB(this.min, this.max.add(1, 1, 1));
}
@Override
public BetterBlockPos pos1() {
return pos1;
}
@Override
public BetterBlockPos pos2() {
return pos2;
}
@Override
public BetterBlockPos min() {
return min;
}
@Override
public BetterBlockPos max() {
return max;
}
@Override
public Vec3i size() {
return size;
}
@Override
public AxisAlignedBB aabb() {
return aabb;
}
@Override
public int hashCode() {
return pos1.hashCode() ^ pos2.hashCode();
}
@Override
public String toString() {
return String.format("Selection{pos1=%s,pos2=%s}", pos1, pos2);
}
/**
* Since it might not be immediately obvious what this does, let me explain.
*
* Let's say you specify EnumFacing.UP, this functions returns if pos2 is the highest BlockPos.
* If you specify EnumFacing.DOWN, it returns if pos2 is the lowest BlockPos.
*
* @param facing The direction to check.
* @return {@code true} if pos2 is further in that direction than pos1, {@code false} if it isn't, and something
* else if they're both at the same position on that axis (it really doesn't matter)
*/
private boolean isPos2(EnumFacing facing) {
boolean negative = facing.getAxisDirection().getOffset() < 0;
switch (facing.getAxis()) {
case X:
return (pos2.x > pos1.x) ^ negative;
case Y:
return (pos2.y > pos1.y) ^ negative;
case Z:
return (pos2.z > pos1.z) ^ negative;
default:
throw new IllegalStateException("Bad EnumFacing.Axis");
}
}
@Override
public ISelection expand(EnumFacing direction, int blocks) {
if (isPos2(direction)) {
return new Selection(pos1, pos2.offset(direction, blocks));
} else {
return new Selection(pos1.offset(direction, blocks), pos2);
}
}
@Override
public ISelection contract(EnumFacing direction, int blocks) {
if (isPos2(direction)) {
return new Selection(pos1.offset(direction, -blocks), pos2);
} else {
return new Selection(pos1, pos2.offset(direction, -blocks));
}
}
@Override
public ISelection shift(EnumFacing direction, int blocks) {
return new Selection(pos1.offset(direction, blocks), pos2.offset(direction, blocks));
}
}

View File

@ -0,0 +1,62 @@
package baritone.selection;
import baritone.api.selection.ISelection;
import baritone.api.selection.ISelectionManager;
import baritone.api.utils.BetterBlockPos;
import java.util.LinkedHashSet;
import java.util.Set;
public class SelectionManager implements ISelectionManager {
private final Set<ISelection> selections = new LinkedHashSet<>();
private ISelection[] selectionsArr = new ISelection[0];
public SelectionManager() {
new SelectionRenderer(this);
}
private void resetSelectionsArr() {
selectionsArr = selections.toArray(new ISelection[0]);
}
@Override
public synchronized ISelection addSelection(ISelection selection) {
selections.add(selection);
resetSelectionsArr();
return selection;
}
@Override
public ISelection addSelection(BetterBlockPos pos1, BetterBlockPos pos2) {
return addSelection(new Selection(pos1, pos2));
}
@Override
public synchronized ISelection removeSelection(ISelection selection) {
selections.remove(selection);
resetSelectionsArr();
return selection;
}
@Override
public synchronized ISelection[] removeAllSelections() {
ISelection[] selectionsArr = getSelections();
selections.clear();
resetSelectionsArr();
return selectionsArr;
}
@Override
public ISelection[] getSelections() {
return selectionsArr;
}
@Override
public synchronized ISelection getOnlySelection() {
if (selections.size() == 1) {
return selections.iterator().next();
}
return null;
}
}

View File

@ -0,0 +1,57 @@
package baritone.selection;
import baritone.api.event.events.RenderEvent;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.selection.ISelection;
import baritone.api.utils.IRenderer;
import net.minecraft.util.math.AxisAlignedBB;
public class SelectionRenderer implements IRenderer, AbstractGameEventListener {
private final SelectionManager manager;
SelectionRenderer(SelectionManager manager) {
this.manager = manager;
baritone.getGameEventHandler().registerEventListener(this);
}
public static void renderSelections(ISelection[] selections) {
boolean ignoreDepth = settings.renderSelectionIgnoreDepth.value;
float lineWidth = settings.selectionRenderLineWidthPixels.value;
if (!settings.renderSelection.value) {
return;
}
IRenderer.startLines(settings.colorSelection.value, lineWidth, ignoreDepth);
for (ISelection selection : selections) {
IRenderer.drawAABB(selection.aabb());
}
IRenderer.endLines(ignoreDepth);
if (!settings.renderSelectionCorners.value) {
return;
}
IRenderer.startLines(settings.colorSelectionPos1.value, lineWidth, ignoreDepth);
for (ISelection selection : selections) {
IRenderer.drawAABB(new AxisAlignedBB(selection.pos1(), selection.pos1().add(1, 1, 1)));
}
IRenderer.endLines(ignoreDepth);
IRenderer.startLines(settings.colorSelectionPos2.value, lineWidth, ignoreDepth);
for (ISelection selection : selections) {
IRenderer.drawAABB(new AxisAlignedBB(selection.pos2(), selection.pos2().add(1, 1, 1)));
}
IRenderer.endLines(ignoreDepth);
}
@Override
public void onRenderPass(RenderEvent event) {
renderSelections(manager.getSelections());
}
}

View File

@ -22,6 +22,7 @@ import baritone.api.BaritoneAPI;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalTwoBlocks;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.IRenderer;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.Entity;
@ -110,7 +111,7 @@ public class GuiClick extends GuiScreen {
GlStateManager.disableDepth();
BetterBlockPos a = new BetterBlockPos(currentMouseOver);
BetterBlockPos b = new BetterBlockPos(clickStart);
PathRenderer.drawAABB(new AxisAlignedBB(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.min(a.z, b.z), Math.max(a.x, b.x) + 1, Math.max(a.y, b.y) + 1, Math.max(a.z, b.z) + 1));
IRenderer.drawAABB(new AxisAlignedBB(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.min(a.z, b.z), Math.max(a.x, b.x) + 1, Math.max(a.y, b.y) + 1, Math.max(a.z, b.z) + 1));
GlStateManager.enableDepth();
GlStateManager.depthMask(true);

View File

@ -17,20 +17,25 @@
package baritone.utils;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.event.events.RenderEvent;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.*;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalComposite;
import baritone.api.pathing.goals.GoalGetToBlock;
import baritone.api.pathing.goals.GoalInverted;
import baritone.api.pathing.goals.GoalTwoBlocks;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.pathing.goals.GoalYLevel;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.api.utils.IRenderer;
import baritone.api.utils.interfaces.IGoalRenderPos;
import baritone.behavior.PathingBehavior;
import baritone.pathing.path.PathExecutor;
import net.minecraft.block.state.IBlockState;
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.tileentity.TileEntityBeaconRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
@ -39,29 +44,30 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import java.awt.*;
import java.awt.Color;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL11.GL_LIGHTING_BIT;
import static org.lwjgl.opengl.GL11.GL_LINES;
import static org.lwjgl.opengl.GL11.GL_LINE_LOOP;
import static org.lwjgl.opengl.GL11.GL_LINE_STRIP;
import static org.lwjgl.opengl.GL11.glPopAttrib;
import static org.lwjgl.opengl.GL11.glPushAttrib;
/**
* @author Brady
* @since 8/9/2018
*/
public final class PathRenderer implements Helper {
private static final Tessellator TESSELLATOR = Tessellator.getInstance();
private static final BufferBuilder BUFFER = TESSELLATOR.getBuffer();
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 (mc.currentScreen instanceof GuiClick) {
((GuiClick) mc.currentScreen).onRender();
if (Helper.mc.currentScreen instanceof GuiClick) {
((GuiClick) Helper.mc.currentScreen).onRender();
}
int thisPlayerDimension = behavior.baritone.getPlayerContext().world().provider.getDimensionType().getId();
@ -72,7 +78,7 @@ public final class PathRenderer implements Helper {
return;
}
Entity renderView = mc.getRenderViewEntity();
Entity renderView = Helper.mc.getRenderViewEntity();
if (renderView.world != BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world()) {
System.out.println("I have no idea what's going on");
@ -81,19 +87,20 @@ public final class PathRenderer implements Helper {
return;
}
if (goal != null && Baritone.settings().renderGoal.value) {
drawDankLitGoalBox(renderView, goal, partialTicks, Baritone.settings().colorGoalBox.value);
if (goal != null && settings.renderGoal.value) {
drawDankLitGoalBox(renderView, goal, partialTicks, settings.colorGoalBox.value);
}
if (!Baritone.settings().renderPath.value) {
if (!settings.renderPath.value) {
return;
}
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 && Baritone.settings().renderSelectionBoxes.value) {
drawManySelectionBoxes(renderView, current.toBreak(), Baritone.settings().colorBlocksToBreak.value);
drawManySelectionBoxes(renderView, current.toPlace(), Baritone.settings().colorBlocksToPlace.value);
drawManySelectionBoxes(renderView, current.toWalkInto(), Baritone.settings().colorBlocksToWalkInto.value);
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(player, Collections.singletonList(behavior.pathStart()), partialTicks, Color.WHITE);
@ -101,63 +108,51 @@ public final class PathRenderer implements Helper {
// Render the current path, if there is one
if (current != null && current.getPath() != null) {
int renderBegin = Math.max(current.getPosition() - 3, 0);
drawPath(current.getPath(), renderBegin, renderView, partialTicks, Baritone.settings().colorCurrentPath.value, Baritone.settings().fadePath.value, 10, 20);
drawPath(current.getPath(), renderBegin, settings.colorCurrentPath.value, settings.fadePath.value, 10, 20);
}
if (next != null && next.getPath() != null) {
drawPath(next.getPath(), 0, renderView, partialTicks, Baritone.settings().colorNextPath.value, Baritone.settings().fadePath.value, 10, 20);
drawPath(next.getPath(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20);
}
// If there is a path calculation currently running, render the path calculation process
behavior.getInProgress().ifPresent(currentlyRunning -> {
currentlyRunning.bestPathSoFar().ifPresent(p -> {
drawPath(p, 0, renderView, partialTicks, Baritone.settings().colorBestPathSoFar.value, Baritone.settings().fadePath.value, 10, 20);
drawPath(p, 0, settings.colorBestPathSoFar.value, settings.fadePath.value, 10, 20);
});
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
drawPath(mr, 0, renderView, partialTicks, Baritone.settings().colorMostRecentConsidered.value, Baritone.settings().fadePath.value, 10, 20);
drawManySelectionBoxes(renderView, Collections.singletonList(mr.getDest()), Baritone.settings().colorMostRecentConsidered.value);
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
drawPath(mr, 0, settings.colorMostRecentConsidered.value, settings.fadePath.value, 10, 20);
drawManySelectionBoxes(renderView, Collections.singletonList(mr.getDest()), settings.colorMostRecentConsidered.value);
});
});
}
public static void drawPath(IPath path, int startIndex, Entity player, float partialTicks, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) {
GlStateManager.enableBlend();
GlStateManager.disableLighting();
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.value);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (Baritone.settings().renderPathIgnoreDepth.value) {
GlStateManager.disableDepth();
}
List<BetterBlockPos> positions = path.positions();
int next;
Tessellator tessellator = Tessellator.getInstance();
public 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;
int fadeEnd = fadeEnd0 + startIndex;
for (int i = startIndex; i < positions.size() - 1; i = next) {
BetterBlockPos start = positions.get(i);
next = i + 1;
BetterBlockPos end = positions.get(next);
List<BetterBlockPos> positions = path.positions();
for (int i = startIndex, next; i < positions.size() - 1; i = next) {
BetterBlockPos start = positions.get(i);
BetterBlockPos end = positions.get(next = i + 1);
int dirX = end.x - start.x;
int dirY = end.y - start.y;
int dirZ = end.z - start.z;
while (next + 1 < positions.size() && (!fadeOut || next + 1 < fadeStart) && (dirX == positions.get(next + 1).x - end.x && dirY == positions.get(next + 1).y - end.y && dirZ == positions.get(next + 1).z - end.z)) {
next++;
end = positions.get(next);
}
double x1 = start.x;
double y1 = start.y;
double z1 = start.z;
double x2 = end.x;
double y2 = end.y;
double z2 = end.z;
if (fadeOut) {
while (next + 1 < positions.size() && (!fadeOut || next + 1 < fadeStart) &&
(dirX == positions.get(next + 1).x - end.x &&
dirY == positions.get(next + 1).y - end.y &&
dirZ == positions.get(next + 1).z - end.z)) {
end = positions.get(++next);
}
if (fadeOut) {
float alpha;
if (i <= fadeStart) {
alpha = 0.4F;
} else {
@ -166,114 +161,68 @@ public final class PathRenderer implements Helper {
}
alpha = 0.4F * (1.0F - (float) (i - fadeStart) / (float) (fadeEnd - fadeStart));
}
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], alpha);
float[] components = color.getComponents(null);
GlStateManager.color(components[0], components[1], components[2], alpha);
}
drawLine(x1, y1, z1, x2, y2, z2);
drawLine(start.x, start.y, start.z, end.x, end.y, end.z);
tessellator.draw();
}
if (Baritone.settings().renderPathIgnoreDepth.value) {
GlStateManager.enableDepth();
}
//GlStateManager.color(0.0f, 0.0f, 0.0f, 0.4f);
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.enableLighting();
GlStateManager.disableBlend();
IRenderer.endLines(settings.renderPathIgnoreDepth.value);
}
public static void drawLine(double bp1x, double bp1y, double bp1z, double bp2x, double bp2y, double bp2z) {
double d0 = mc.getRenderManager().viewerPosX;
double d1 = mc.getRenderManager().viewerPosY;
double d2 = mc.getRenderManager().viewerPosZ;
boolean renderPathAsFrickinThingy = !Baritone.settings().renderPathAsLine.value;
public static void drawLine(double x1, double y1, double z1, double x2, double y2, double z2) {
RenderManager renderManager = Helper.mc.getRenderManager();
double vpX = renderManager.viewerPosX;
double vpY = renderManager.viewerPosY;
double vpZ = renderManager.viewerPosZ;
boolean renderPathAsFrickinThingy = !settings.renderPathAsLine.value;
BUFFER.begin(renderPathAsFrickinThingy ? GL_LINE_STRIP : GL_LINES, DefaultVertexFormats.POSITION);
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.5D - d1, bp1z + 0.5D - d2).endVertex();
BUFFER.pos(bp2x + 0.5D - d0, bp2y + 0.5D - d1, bp2z + 0.5D - d2).endVertex();
buffer.begin(renderPathAsFrickinThingy ? GL_LINE_STRIP : GL_LINES, DefaultVertexFormats.POSITION);
buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).endVertex();
buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).endVertex();
if (renderPathAsFrickinThingy) {
BUFFER.pos(bp2x + 0.5D - d0, bp2y + 0.53D - d1, bp2z + 0.5D - d2).endVertex();
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.53D - d1, bp1z + 0.5D - d2).endVertex();
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.5D - d1, bp1z + 0.5D - d2).endVertex();
buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).endVertex();
buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).endVertex();
buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).endVertex();
}
}
public static void drawManySelectionBoxes(Entity player, Collection<BlockPos> positions, Color color) {
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.value);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.value) {
GlStateManager.disableDepth();
}
IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderSelectionBoxesIgnoreDepth.value);
//BlockPos blockpos = movingObjectPositionIn.getBlockPos();
BlockStateInterface bsi = new BlockStateInterface(BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext()); // TODO this assumes same dimension between primary baritone and render view? is this safe?
positions.forEach(pos -> {
IBlockState state = bsi.get0(pos);
AxisAlignedBB toDraw;
if (state.getBlock().equals(Blocks.AIR)) {
toDraw = Blocks.DIRT.getDefaultState().getSelectedBoundingBox(player.world, pos);
} else {
toDraw = state.getSelectedBoundingBox(player.world, pos);
}
drawAABB(toDraw);
IRenderer.drawAABB(toDraw);
});
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.value) {
GlStateManager.enableDepth();
}
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
}
public static void drawAABB(AxisAlignedBB aabb) {
float expand = 0.002F;
AxisAlignedBB toDraw = aabb.expand(expand, expand, expand).offset(-mc.getRenderManager().viewerPosX, -mc.getRenderManager().viewerPosY, -mc.getRenderManager().viewerPosZ);
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
TESSELLATOR.draw();
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
TESSELLATOR.draw();
BUFFER.begin(GL_LINES, DefaultVertexFormats.POSITION);
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
TESSELLATOR.draw();
IRenderer.endLines(settings.renderSelectionBoxesIgnoreDepth.value);
}
public static void drawDankLitGoalBox(Entity player, Goal goal, float partialTicks, Color color) {
double renderPosX = mc.getRenderManager().viewerPosX;
double renderPosY = mc.getRenderManager().viewerPosY;
double renderPosZ = mc.getRenderManager().viewerPosZ;
double minX;
double maxX;
double minZ;
double maxZ;
double minY;
double maxY;
double y1;
double y2;
RenderManager renderManager = Helper.mc.getRenderManager();
double renderPosX = renderManager.viewerPosX;
double renderPosY = renderManager.viewerPosY;
double renderPosZ = renderManager.viewerPosZ;
double minX, maxX;
double minZ, maxZ;
double minY, maxY;
double y1, y2;
double y = MathHelper.cos((float) (((float) ((System.nanoTime() / 100000L) % 20000L)) / 20000F * Math.PI * 2));
if (goal instanceof IGoalRenderPos) {
BlockPos goalPos = ((IGoalRenderPos) goal).getGoalPos();
@ -296,28 +245,28 @@ public final class PathRenderer implements Helper {
} else if (goal instanceof GoalXZ) {
GoalXZ goalPos = (GoalXZ) goal;
if (Baritone.settings().renderGoalXZBeacon.value) {
if (settings.renderGoalXZBeacon.value) {
glPushAttrib(GL_LIGHTING_BIT);
mc.getTextureManager().bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM);
Helper.mc.getTextureManager().bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM);
if (Baritone.settings().renderGoalIgnoreDepth.value) {
if (settings.renderGoalIgnoreDepth.value) {
GlStateManager.disableDepth();
}
TileEntityBeaconRenderer.renderBeamSegment(
goalPos.getX() - renderPosX,
-renderPosY,
goalPos.getZ() - renderPosZ,
partialTicks,
1.0,
player.world.getTotalWorldTime(),
0,
256,
color.getColorComponents(null)
goalPos.getX() - renderPosX,
-renderPosY,
goalPos.getZ() - renderPosZ,
partialTicks,
1.0,
player.world.getTotalWorldTime(),
0,
256,
color.getColorComponents(null)
);
if (Baritone.settings().renderGoalIgnoreDepth.value) {
if (settings.renderGoalIgnoreDepth.value) {
GlStateManager.enableDepth();
}
@ -340,14 +289,14 @@ public final class PathRenderer implements Helper {
}
return;
} else if (goal instanceof GoalInverted) {
drawDankLitGoalBox(player, ((GoalInverted) goal).origin, partialTicks, Baritone.settings().colorInvertedGoalBox.value);
drawDankLitGoalBox(player, ((GoalInverted) goal).origin, partialTicks, settings.colorInvertedGoalBox.value);
return;
} else if (goal instanceof GoalYLevel) {
GoalYLevel goalpos = (GoalYLevel) goal;
minX = player.posX - Baritone.settings().yLevelBoxSize.value - renderPosX;
minZ = player.posZ - Baritone.settings().yLevelBoxSize.value - renderPosZ;
maxX = player.posX + Baritone.settings().yLevelBoxSize.value - renderPosX;
maxZ = player.posZ + Baritone.settings().yLevelBoxSize.value - renderPosZ;
minX = player.posX - settings.yLevelBoxSize.value - renderPosX;
minZ = player.posZ - settings.yLevelBoxSize.value - renderPosZ;
maxX = player.posX + settings.yLevelBoxSize.value - renderPosX;
maxZ = player.posZ + settings.yLevelBoxSize.value - renderPosZ;
minY = ((GoalYLevel) goal).level - renderPosY;
maxY = minY + 2;
y1 = 1 + y + goalpos.level - renderPosY;
@ -356,46 +305,33 @@ public final class PathRenderer implements Helper {
return;
}
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.6F);
GlStateManager.glLineWidth(Baritone.settings().goalRenderLineWidthPixels.value);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
if (Baritone.settings().renderGoalIgnoreDepth.value) {
GlStateManager.disableDepth();
}
IRenderer.startLines(color, settings.goalRenderLineWidthPixels.value, settings.renderGoalIgnoreDepth.value);
renderHorizontalQuad(minX, maxX, minZ, maxZ, y1);
renderHorizontalQuad(minX, maxX, minZ, maxZ, y2);
BUFFER.begin(GL_LINES, DefaultVertexFormats.POSITION);
BUFFER.pos(minX, minY, minZ).endVertex();
BUFFER.pos(minX, maxY, minZ).endVertex();
BUFFER.pos(maxX, minY, minZ).endVertex();
BUFFER.pos(maxX, maxY, minZ).endVertex();
BUFFER.pos(maxX, minY, maxZ).endVertex();
BUFFER.pos(maxX, maxY, maxZ).endVertex();
BUFFER.pos(minX, minY, maxZ).endVertex();
BUFFER.pos(minX, maxY, maxZ).endVertex();
TESSELLATOR.draw();
buffer.begin(GL_LINES, DefaultVertexFormats.POSITION);
buffer.pos(minX, minY, minZ).endVertex();
buffer.pos(minX, maxY, minZ).endVertex();
buffer.pos(maxX, minY, minZ).endVertex();
buffer.pos(maxX, maxY, minZ).endVertex();
buffer.pos(maxX, minY, maxZ).endVertex();
buffer.pos(maxX, maxY, maxZ).endVertex();
buffer.pos(minX, minY, maxZ).endVertex();
buffer.pos(minX, maxY, maxZ).endVertex();
tessellator.draw();
if (Baritone.settings().renderGoalIgnoreDepth.value) {
GlStateManager.enableDepth();
}
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
IRenderer.endLines(settings.renderGoalIgnoreDepth.value);
}
private static void renderHorizontalQuad(double minX, double maxX, double minZ, double maxZ, double y) {
if (y != 0) {
BUFFER.begin(GL_LINE_LOOP, DefaultVertexFormats.POSITION);
BUFFER.pos(minX, y, minZ).endVertex();
BUFFER.pos(maxX, y, minZ).endVertex();
BUFFER.pos(maxX, y, maxZ).endVertex();
BUFFER.pos(minX, y, maxZ).endVertex();
TESSELLATOR.draw();
buffer.begin(GL_LINE_LOOP, DefaultVertexFormats.POSITION);
buffer.pos(minX, y, minZ).endVertex();
buffer.pos(maxX, y, minZ).endVertex();
buffer.pos(maxX, y, maxZ).endVertex();
buffer.pos(minX, y, maxZ).endVertex();
tessellator.draw();
}
}
}