Merge branch 'master' into 1.13.2
This commit is contained in:
@@ -19,7 +19,7 @@
|
|||||||

|

|
||||||
[](https://github.com/cabaletta/baritone/graphs/contributors/)
|
[](https://github.com/cabaletta/baritone/graphs/contributors/)
|
||||||
[](https://github.com/cabaletta/baritone/commit/)
|
[](https://github.com/cabaletta/baritone/commit/)
|
||||||
[](https://impactclient.net/)
|
[](https://impactclient.net/)
|
||||||
[](https://github.com/fr1kin/ForgeHax/)
|
[](https://github.com/fr1kin/ForgeHax/)
|
||||||
[](https://gitlab.com/emc-mods-indrit/baritone_api)
|
[](https://gitlab.com/emc-mods-indrit/baritone_api)
|
||||||
[](https://wweclient.com/)
|
[](https://wweclient.com/)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Try `#help` I promise it won't just send you back here =)
|
|||||||
|
|
||||||
"wtf where is cleararea" -> look at `#help sel`
|
"wtf where is cleararea" -> look at `#help sel`
|
||||||
|
|
||||||
"wtf where is goto death, goto waypoint" -> look at `#help wp`
|
"wtf where is goto death, goto waypoint" -> look at `#help wp` (a "tag" is like "home" (created automatically on right clicking a bed) or "death" (created automatically on death) or "user" (has to be created manually)). So you might want `#wp save user coolbiome` then, to set the goal `#wp goal coolbiome` then `#path` to path to it. For death, `#wp goal death` (remember stuff is clickable!).
|
||||||
|
|
||||||
just look at `#help` lmao
|
just look at `#help` lmao
|
||||||
|
|
||||||
|
|||||||
@@ -183,6 +183,20 @@ public final class Settings {
|
|||||||
Blocks.WALL_SIGN
|
Blocks.WALL_SIGN
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of blocks to be treated as if they're air.
|
||||||
|
* <p>
|
||||||
|
* If a schematic asks for air at a certain position, and that position currently contains a block on this list, it will be treated as correct.
|
||||||
|
*/
|
||||||
|
public final Setting<List<Block>> buildIgnoreBlocks = new Setting<>(new ArrayList<>(Arrays.asList(
|
||||||
|
|
||||||
|
)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this is true, the builder will treat all non-air blocks as correct. It will only place new blocks.
|
||||||
|
*/
|
||||||
|
public final Setting<Boolean> buildIgnoreExisting = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
|
* If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -233,7 +247,7 @@ public final class Settings {
|
|||||||
/**
|
/**
|
||||||
* If we overshoot a traverse and end up one block beyond the destination, mark it as successful anyway.
|
* If we overshoot a traverse and end up one block beyond the destination, mark it as successful anyway.
|
||||||
* <p>
|
* <p>
|
||||||
* This helps with speed at >=20m/s
|
* This helps with speed exceeding 20m/s
|
||||||
*/
|
*/
|
||||||
public final Setting<Boolean> overshootTraverse = new Setting<>(true);
|
public final Setting<Boolean> overshootTraverse = new Setting<>(true);
|
||||||
|
|
||||||
@@ -252,6 +266,11 @@ public final class Settings {
|
|||||||
*/
|
*/
|
||||||
public final Setting<Double> randomLooking113 = new Setting<>(2d);
|
public final Setting<Double> randomLooking113 = new Setting<>(2d);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block reach distance
|
||||||
|
*/
|
||||||
|
public final Setting<Float> blockReachDistance = new Setting<>(4.5f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How many degrees to randomize the pitch and yaw every tick. Set to 0 to disable
|
* How many degrees to randomize the pitch and yaw every tick. Set to 0 to disable
|
||||||
*/
|
*/
|
||||||
@@ -742,6 +761,11 @@ public final class Settings {
|
|||||||
*/
|
*/
|
||||||
public final Setting<Vec3i> buildRepeat = new Setting<>(new Vec3i(0, 0, 0));
|
public final Setting<Vec3i> buildRepeat = new Setting<>(new Vec3i(0, 0, 0));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many times to buildrepeat. -1 for infinite.
|
||||||
|
*/
|
||||||
|
public final Setting<Integer> buildRepeatCount = new Setting<>(-1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow standing above a block while mining it, in BuilderProcess
|
* Allow standing above a block while mining it, in BuilderProcess
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -38,38 +38,26 @@ public enum RelativeGoal implements IDatatypePost<Goal, BetterBlockPos> {
|
|||||||
if (origin == null) {
|
if (origin == null) {
|
||||||
origin = BetterBlockPos.ORIGIN;
|
origin = BetterBlockPos.ORIGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
final IArgConsumer consumer = ctx.getConsumer();
|
final IArgConsumer consumer = ctx.getConsumer();
|
||||||
|
|
||||||
List<IDatatypePostFunction<Double, Double>> coords = new ArrayList<>();
|
GoalBlock goalBlock = consumer.peekDatatypePostOrNull(RelativeGoalBlock.INSTANCE, origin);
|
||||||
final IArgConsumer copy = consumer.copy(); // This is a hack and should be fixed in the future probably
|
if (goalBlock != null) {
|
||||||
for (int i = 0; i < 3; i++) {
|
return goalBlock;
|
||||||
if (copy.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) {
|
|
||||||
coords.add(o -> consumer.getDatatypePost(RelativeCoordinate.INSTANCE, o));
|
|
||||||
copy.get(); // Consume so we actually decrement the remaining arguments
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (coords.size()) {
|
GoalXZ goalXZ = consumer.peekDatatypePostOrNull(RelativeGoalXZ.INSTANCE, origin);
|
||||||
case 0:
|
if (goalXZ != null) {
|
||||||
return new GoalBlock(origin);
|
return goalXZ;
|
||||||
case 1:
|
|
||||||
return new GoalYLevel(
|
|
||||||
MathHelper.floor(coords.get(0).apply((double) origin.y))
|
|
||||||
);
|
|
||||||
case 2:
|
|
||||||
return new GoalXZ(
|
|
||||||
MathHelper.floor(coords.get(0).apply((double) origin.x)),
|
|
||||||
MathHelper.floor(coords.get(1).apply((double) origin.z))
|
|
||||||
);
|
|
||||||
case 3:
|
|
||||||
return new GoalBlock(
|
|
||||||
MathHelper.floor(coords.get(0).apply((double) origin.x)),
|
|
||||||
MathHelper.floor(coords.get(1).apply((double) origin.y)),
|
|
||||||
MathHelper.floor(coords.get(2).apply((double) origin.z))
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("Unexpected coords size: " + coords.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GoalYLevel goalYLevel = consumer.peekDatatypePostOrNull(RelativeGoalYLevel.INSTANCE, origin);
|
||||||
|
if (goalYLevel != null) {
|
||||||
|
return goalYLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// when the user doesn't input anything, default to the origin
|
||||||
|
return new GoalBlock(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -22,4 +22,8 @@ public abstract class CommandErrorMessageException extends CommandException {
|
|||||||
protected CommandErrorMessageException(String reason) {
|
protected CommandErrorMessageException(String reason) {
|
||||||
super(reason);
|
super(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected CommandErrorMessageException(String reason, Throwable cause) {
|
||||||
|
super(reason, cause);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,4 +22,8 @@ public abstract class CommandException extends Exception implements ICommandExce
|
|||||||
protected CommandException(String reason) {
|
protected CommandException(String reason) {
|
||||||
super(reason);
|
super(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected CommandException(String reason, Throwable cause) {
|
||||||
|
super(reason, cause);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,12 +23,21 @@ public abstract class CommandInvalidArgumentException extends CommandErrorMessag
|
|||||||
|
|
||||||
public final ICommandArgument arg;
|
public final ICommandArgument arg;
|
||||||
|
|
||||||
protected CommandInvalidArgumentException(ICommandArgument arg, String reason) {
|
protected CommandInvalidArgumentException(ICommandArgument arg, String message) {
|
||||||
super(String.format(
|
super(formatMessage(arg, message));
|
||||||
"Error at argument #%s: %s",
|
|
||||||
arg.getIndex() == -1 ? "<unknown>" : Integer.toString(arg.getIndex() + 1),
|
|
||||||
reason
|
|
||||||
));
|
|
||||||
this.arg = arg;
|
this.arg = arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected CommandInvalidArgumentException(ICommandArgument arg, String message, Throwable cause) {
|
||||||
|
super(formatMessage(arg, message), cause);
|
||||||
|
this.arg = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String formatMessage(ICommandArgument arg, String message) {
|
||||||
|
return String.format(
|
||||||
|
"Error at argument #%s: %s",
|
||||||
|
arg.getIndex() == -1 ? "<unknown>" : Integer.toString(arg.getIndex() + 1),
|
||||||
|
message
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class CommandInvalidTypeException extends CommandInvalidArgumentException
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CommandInvalidTypeException(ICommandArgument arg, String expected, Throwable cause) {
|
public CommandInvalidTypeException(ICommandArgument arg, String expected, Throwable cause) {
|
||||||
super(arg, String.format("Expected %s.\nMore details: %s", expected, cause.getMessage()));
|
super(arg, String.format("Expected %s", expected), cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandInvalidTypeException(ICommandArgument arg, String expected, String got) {
|
public CommandInvalidTypeException(ICommandArgument arg, String expected, String got) {
|
||||||
@@ -34,6 +34,6 @@ public class CommandInvalidTypeException extends CommandInvalidArgumentException
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CommandInvalidTypeException(ICommandArgument arg, String expected, String got, Throwable cause) {
|
public CommandInvalidTypeException(ICommandArgument arg, String expected, String got, Throwable cause) {
|
||||||
super(arg, String.format("Expected %s, but got %s instead.\nMore details: %s", expected, got, cause.getMessage()));
|
super(arg, String.format("Expected %s, but got %s instead", expected, got), cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class CommandUnhandledException extends RuntimeException implements IComm
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(ICommand command, List<ICommandArgument> args) {
|
public void handle(ICommand command, List<ICommandArgument> args) {
|
||||||
HELPER.logDirect("An unhandled exception occurred." +
|
HELPER.logDirect("An unhandled exception occurred. " +
|
||||||
"The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues",
|
"The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues",
|
||||||
TextFormatting.RED);
|
TextFormatting.RED);
|
||||||
|
|
||||||
|
|||||||
@@ -19,22 +19,20 @@ package baritone.api.event.events;
|
|||||||
|
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
public final class TickEvent {
|
public final class TickEvent {
|
||||||
|
|
||||||
|
private static int overallTickCount;
|
||||||
|
|
||||||
private final EventState state;
|
private final EventState state;
|
||||||
private final Type type;
|
private final Type type;
|
||||||
private final int count;
|
private final int count;
|
||||||
|
|
||||||
private static int overallTickCount;
|
public TickEvent(EventState state, Type type, int count) {
|
||||||
|
|
||||||
public TickEvent(EventState state, Type type) {
|
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.count = incrementCount();
|
this.count = count;
|
||||||
}
|
|
||||||
|
|
||||||
private static synchronized int incrementCount() {
|
|
||||||
return overallTickCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
@@ -49,6 +47,10 @@ public final class TickEvent {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static synchronized BiFunction<EventState, Type, TickEvent> createNextProvider() {
|
||||||
|
final int count = overallTickCount++;
|
||||||
|
return (state, type) -> new TickEvent(state, type, count);
|
||||||
|
}
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.api.utils;
|
package baritone.api.utils;
|
||||||
|
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.inventory.ClickType;
|
import net.minecraft.inventory.ClickType;
|
||||||
@@ -56,6 +57,6 @@ public interface IPlayerController {
|
|||||||
void setHittingBlock(boolean hittingBlock);
|
void setHittingBlock(boolean hittingBlock);
|
||||||
|
|
||||||
default double getBlockReachDistance() {
|
default double getBlockReachDistance() {
|
||||||
return this.getGameType().isCreative() ? 5.0F : 4.5F;
|
return this.getGameType().isCreative() ? 5.0F : BaritoneAPI.getSettings().blockReachDistance.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 7/31/2018
|
* @since 7/31/2018
|
||||||
@@ -84,13 +86,15 @@ public class MixinMinecraft {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void runTick(CallbackInfo ci) {
|
private void runTick(CallbackInfo ci) {
|
||||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
final BiFunction<EventState, TickEvent.Type, TickEvent> tickProvider = TickEvent.createNextProvider();
|
||||||
|
|
||||||
TickEvent.Type type = ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().world() != null
|
for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
|
|
||||||
|
TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null
|
||||||
? TickEvent.Type.IN
|
? TickEvent.Type.IN
|
||||||
: TickEvent.Type.OUT;
|
: TickEvent.Type.OUT;
|
||||||
|
|
||||||
ibaritone.getGameEventHandler().onTick(new TickEvent(EventState.PRE, type));
|
baritone.getGameEventHandler().onTick(tickProvider.apply(EventState.PRE, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -316,8 +316,7 @@ public class ArgConsumer implements IArgConsumer {
|
|||||||
try {
|
try {
|
||||||
return datatype.apply(this.context, original);
|
return datatype.apply(this.context, original);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName(), e);
|
||||||
throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,7 +345,7 @@ public class ArgConsumer implements IArgConsumer {
|
|||||||
try {
|
try {
|
||||||
return datatype.get(this.context);
|
return datatype.get(this.context);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName());
|
throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.command.defaults;
|
|
||||||
|
|
||||||
import baritone.api.IBaritone;
|
|
||||||
import baritone.api.command.Command;
|
|
||||||
import baritone.api.command.exception.CommandException;
|
|
||||||
import baritone.api.command.argument.IArgConsumer;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class CancelCommand extends Command {
|
|
||||||
|
|
||||||
public CancelCommand(IBaritone baritone) {
|
|
||||||
super(baritone, "cancel", "stop");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(String label, IArgConsumer args) throws CommandException {
|
|
||||||
args.requireMax(0);
|
|
||||||
baritone.getPathingBehavior().cancelEverything();
|
|
||||||
logDirect("ok canceled");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<String> tabComplete(String label, IArgConsumer args) {
|
|
||||||
return Stream.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getShortDesc() {
|
|
||||||
return "Cancel what Baritone is currently doing";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getLongDesc() {
|
|
||||||
return Arrays.asList(
|
|
||||||
"The cancel command tells Baritone to stop whatever it's currently doing.",
|
|
||||||
"",
|
|
||||||
"Usage:",
|
|
||||||
"> cancel"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,52 +24,53 @@ import java.util.*;
|
|||||||
|
|
||||||
public final class DefaultCommands {
|
public final class DefaultCommands {
|
||||||
|
|
||||||
private DefaultCommands() {}
|
private DefaultCommands() {
|
||||||
|
}
|
||||||
|
|
||||||
public static List<ICommand> createAll(IBaritone baritone) {
|
public static List<ICommand> createAll(IBaritone baritone) {
|
||||||
Objects.requireNonNull(baritone);
|
Objects.requireNonNull(baritone);
|
||||||
List<ICommand> commands = new ArrayList<>(Arrays.asList(
|
List<ICommand> commands = new ArrayList<>(Arrays.asList(
|
||||||
new HelpCommand(baritone),
|
new HelpCommand(baritone),
|
||||||
new SetCommand(baritone),
|
new SetCommand(baritone),
|
||||||
new CommandAlias(baritone, Arrays.asList("modified", "mod", "baritone", "modifiedsettings"), "List modified settings", "set modified"),
|
new CommandAlias(baritone, Arrays.asList("modified", "mod", "baritone", "modifiedsettings"), "List modified settings", "set modified"),
|
||||||
new CommandAlias(baritone, "reset", "Reset all settings or just one", "set reset"),
|
new CommandAlias(baritone, "reset", "Reset all settings or just one", "set reset"),
|
||||||
new GoalCommand(baritone),
|
new GoalCommand(baritone),
|
||||||
new GotoCommand(baritone),
|
new GotoCommand(baritone),
|
||||||
new PathCommand(baritone),
|
new PathCommand(baritone),
|
||||||
new ProcCommand(baritone),
|
new ProcCommand(baritone),
|
||||||
new VersionCommand(baritone),
|
new VersionCommand(baritone),
|
||||||
new RepackCommand(baritone),
|
new RepackCommand(baritone),
|
||||||
new BuildCommand(baritone),
|
new BuildCommand(baritone),
|
||||||
new SchematicaCommand(baritone),
|
new SchematicaCommand(baritone),
|
||||||
new ComeCommand(baritone),
|
new ComeCommand(baritone),
|
||||||
new AxisCommand(baritone),
|
new AxisCommand(baritone),
|
||||||
new CancelCommand(baritone),
|
new ForceCancelCommand(baritone),
|
||||||
new ForceCancelCommand(baritone),
|
new GcCommand(baritone),
|
||||||
new GcCommand(baritone),
|
new InvertCommand(baritone),
|
||||||
new InvertCommand(baritone),
|
new TunnelCommand(baritone),
|
||||||
new TunnelCommand(baritone),
|
new RenderCommand(baritone),
|
||||||
new RenderCommand(baritone),
|
new FarmCommand(baritone),
|
||||||
new FarmCommand(baritone),
|
new ChestsCommand(baritone),
|
||||||
new ChestsCommand(baritone),
|
new FollowCommand(baritone),
|
||||||
new FollowCommand(baritone),
|
new ExploreFilterCommand(baritone),
|
||||||
new ExploreFilterCommand(baritone),
|
new ReloadAllCommand(baritone),
|
||||||
new ReloadAllCommand(baritone),
|
new SaveAllCommand(baritone),
|
||||||
new SaveAllCommand(baritone),
|
new ExploreCommand(baritone),
|
||||||
new ExploreCommand(baritone),
|
new BlacklistCommand(baritone),
|
||||||
new BlacklistCommand(baritone),
|
new FindCommand(baritone),
|
||||||
new FindCommand(baritone),
|
new MineCommand(baritone),
|
||||||
new MineCommand(baritone),
|
new ClickCommand(baritone),
|
||||||
new ClickCommand(baritone),
|
new ThisWayCommand(baritone),
|
||||||
new ThisWayCommand(baritone),
|
new WaypointsCommand(baritone),
|
||||||
new WaypointsCommand(baritone),
|
new CommandAlias(baritone, "sethome", "Sets your home waypoint", "waypoints save home"),
|
||||||
new CommandAlias(baritone, "sethome", "Sets your home waypoint", "waypoints save home"),
|
new CommandAlias(baritone, "home", "Set goal to your home waypoint", "waypoints goal home"),
|
||||||
new CommandAlias(baritone, "home", "Set goal to your home waypoint", "waypoints goal home"),
|
new SelCommand(baritone)
|
||||||
new SelCommand(baritone)
|
|
||||||
));
|
));
|
||||||
PauseResumeCommands prc = new PauseResumeCommands(baritone);
|
ExecutionControlCommands prc = new ExecutionControlCommands(baritone);
|
||||||
commands.add(prc.pauseCommand);
|
commands.add(prc.pauseCommand);
|
||||||
commands.add(prc.resumeCommand);
|
commands.add(prc.resumeCommand);
|
||||||
commands.add(prc.pausedCommand);
|
commands.add(prc.pausedCommand);
|
||||||
|
commands.add(prc.cancelCommand);
|
||||||
return Collections.unmodifiableList(commands);
|
return Collections.unmodifiableList(commands);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-7
@@ -18,13 +18,13 @@
|
|||||||
package baritone.command.defaults;
|
package baritone.command.defaults;
|
||||||
|
|
||||||
import baritone.api.IBaritone;
|
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.process.IBaritoneProcess;
|
import baritone.api.process.IBaritoneProcess;
|
||||||
import baritone.api.process.PathingCommand;
|
import baritone.api.process.PathingCommand;
|
||||||
import baritone.api.process.PathingCommandType;
|
import baritone.api.process.PathingCommandType;
|
||||||
import baritone.api.command.Command;
|
|
||||||
import baritone.api.command.exception.CommandException;
|
|
||||||
import baritone.api.command.exception.CommandInvalidStateException;
|
|
||||||
import baritone.api.command.argument.IArgConsumer;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -37,13 +37,14 @@ import java.util.stream.Stream;
|
|||||||
* TO USE THIS to pause and resume Baritone. Make your own process that returns {@link PathingCommandType#REQUEST_PAUSE
|
* TO USE THIS to pause and resume Baritone. Make your own process that returns {@link PathingCommandType#REQUEST_PAUSE
|
||||||
* REQUEST_PAUSE} as needed.
|
* REQUEST_PAUSE} as needed.
|
||||||
*/
|
*/
|
||||||
public class PauseResumeCommands {
|
public class ExecutionControlCommands {
|
||||||
|
|
||||||
Command pauseCommand;
|
Command pauseCommand;
|
||||||
Command resumeCommand;
|
Command resumeCommand;
|
||||||
Command pausedCommand;
|
Command pausedCommand;
|
||||||
|
Command cancelCommand;
|
||||||
|
|
||||||
public PauseResumeCommands(IBaritone baritone) {
|
public ExecutionControlCommands(IBaritone baritone) {
|
||||||
// array for mutability, non-field so reflection can't touch it
|
// array for mutability, non-field so reflection can't touch it
|
||||||
final boolean[] paused = {false};
|
final boolean[] paused = {false};
|
||||||
baritone.getPathingControlManager().registerProcess(
|
baritone.getPathingControlManager().registerProcess(
|
||||||
@@ -64,7 +65,8 @@ public class PauseResumeCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLostControl() {}
|
public void onLostControl() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double priority() {
|
public double priority() {
|
||||||
@@ -169,5 +171,36 @@ public class PauseResumeCommands {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
cancelCommand = new Command(baritone, "cancel", "stop") {
|
||||||
|
@Override
|
||||||
|
public void execute(String label, IArgConsumer args) throws CommandException {
|
||||||
|
args.requireMax(0);
|
||||||
|
if (paused[0]) {
|
||||||
|
paused[0] = false;
|
||||||
|
}
|
||||||
|
baritone.getPathingBehavior().cancelEverything();
|
||||||
|
logDirect("ok canceled");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<String> tabComplete(String label, IArgConsumer args) {
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getShortDesc() {
|
||||||
|
return "Cancel what Baritone is currently doing";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getLongDesc() {
|
||||||
|
return Arrays.asList(
|
||||||
|
"The cancel command tells Baritone to stop whatever it's currently doing.",
|
||||||
|
"",
|
||||||
|
"Usage:",
|
||||||
|
"> cancel"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,9 +41,13 @@ public class GotoCommand extends Command {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(String label, IArgConsumer args) throws CommandException {
|
public void execute(String label, IArgConsumer args) throws CommandException {
|
||||||
if (args.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) { // if we have a numeric first argument...
|
// If we have a numeric first argument, then parse arguments as coordinates.
|
||||||
|
// Note: There is no reason to want to go where you're already at so there
|
||||||
|
// is no need to handle the case of empty arguments.
|
||||||
|
if (args.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) {
|
||||||
|
args.requireMax(3);
|
||||||
BetterBlockPos origin = baritone.getPlayerContext().playerFeet();
|
BetterBlockPos origin = baritone.getPlayerContext().playerFeet();
|
||||||
Goal goal = args.getDatatypePostOrNull(RelativeGoal.INSTANCE, origin);
|
Goal goal = args.getDatatypePost(RelativeGoal.INSTANCE, origin);
|
||||||
logDirect(String.format("Going to: %s", goal.toString()));
|
logDirect(String.format("Going to: %s", goal.toString()));
|
||||||
baritone.getCustomGoalProcess().setGoalAndPath(goal);
|
baritone.getCustomGoalProcess().setGoalAndPath(goal);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import net.minecraft.util.EnumFacing;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -143,7 +144,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
// every block that overrides isPassable with anything more complicated than a "return true;" or "return false;"
|
// every block that overrides isPassable with anything more complicated than a "return true;" or "return false;"
|
||||||
// has already been accounted for above
|
// has already been accounted for above
|
||||||
// therefore it's safe to not construct a blockpos from our x, y, z ints and instead just pass null
|
// therefore it's safe to not construct a blockpos from our x, y, z ints and instead just pass null
|
||||||
return state.allowsMovement(null, BlockPos.ORIGIN, PathType.LAND); // workaround for future compatibility =P
|
return state.allowsMovement(bsi.access, BlockPos.ORIGIN, PathType.LAND); // workaround for future compatibility =P
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,10 +158,18 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
* @return Whether or not the block at the specified position
|
* @return Whether or not the block at the specified position
|
||||||
*/
|
*/
|
||||||
static boolean fullyPassable(CalculationContext context, int x, int y, int z) {
|
static boolean fullyPassable(CalculationContext context, int x, int y, int z) {
|
||||||
return fullyPassable(context.get(x, y, z));
|
return fullyPassable(
|
||||||
|
context.bsi.access,
|
||||||
|
context.bsi.isPassableBlockPos.setPos(x, y, z),
|
||||||
|
context.bsi.get0(x, y, z)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean fullyPassable(IBlockState state) {
|
static boolean fullyPassable(IPlayerContext ctx, BlockPos pos) {
|
||||||
|
return fullyPassable(ctx.world(), pos, ctx.world().getBlockState(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean fullyPassable(IBlockReader access, BlockPos pos, IBlockState state) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block instanceof BlockAir) { // early return for most common case
|
if (block instanceof BlockAir) { // early return for most common case
|
||||||
return true;
|
return true;
|
||||||
@@ -183,7 +192,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
|
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
|
||||||
return state.allowsMovement(null, null, PathType.LAND);
|
return state.allowsMovement(access, pos, PathType.LAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isReplaceable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
|
static boolean isReplaceable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public class MovementParkour extends Movement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState destInto = context.bsi.get0(destX, y, destZ);
|
IBlockState destInto = context.bsi.get0(destX, y, destZ);
|
||||||
if (!MovementHelper.fullyPassable(destInto)) {
|
if (!MovementHelper.fullyPassable(context.bsi.access, context.bsi.isPassableBlockPos.setPos(destX, y, destZ), destInto)) {
|
||||||
if (i <= 3 && context.allowParkourAscend && context.canSprint && MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) && checkOvershootSafety(context.bsi, destX + xDiff, y + 1, destZ + zDiff)) {
|
if (i <= 3 && context.allowParkourAscend && context.canSprint && MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) && checkOvershootSafety(context.bsi, destX + xDiff, y + 1, destZ + zDiff)) {
|
||||||
res.x = destX;
|
res.x = destX;
|
||||||
res.y = y + 1;
|
res.y = y + 1;
|
||||||
|
|||||||
@@ -465,7 +465,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
}
|
}
|
||||||
for (int y = next.getDest().y; y <= movement.getSrc().y + 1; y++) {
|
for (int y = next.getDest().y; y <= movement.getSrc().y + 1; y++) {
|
||||||
BlockPos chk = new BlockPos(next.getDest().x, y, next.getDest().z);
|
BlockPos chk = new BlockPos(next.getDest().x, y, next.getDest().z);
|
||||||
if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) {
|
if (!MovementHelper.fullyPassable(ctx, chk)) {
|
||||||
break outer;
|
break outer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -490,7 +490,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
}
|
}
|
||||||
// we are centered
|
// we are centered
|
||||||
BlockPos headBonk = current.getSrc().subtract(current.getDirection()).up(2);
|
BlockPos headBonk = current.getSrc().subtract(current.getDirection()).up(2);
|
||||||
if (MovementHelper.fullyPassable(ctx.world().getBlockState(headBonk))) {
|
if (MovementHelper.fullyPassable(ctx, headBonk)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// wait 0.3
|
// wait 0.3
|
||||||
@@ -523,7 +523,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
if (x == 1) {
|
if (x == 1) {
|
||||||
chk = chk.add(current.getDirection());
|
chk = chk.add(current.getDirection());
|
||||||
}
|
}
|
||||||
if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) {
|
if (!MovementHelper.fullyPassable(ctx, chk)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ import baritone.api.process.IBuilderProcess;
|
|||||||
import baritone.api.process.PathingCommand;
|
import baritone.api.process.PathingCommand;
|
||||||
import baritone.api.process.PathingCommandType;
|
import baritone.api.process.PathingCommandType;
|
||||||
import baritone.api.schematic.ISchematic;
|
import baritone.api.schematic.ISchematic;
|
||||||
import baritone.api.utils.*;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import baritone.api.utils.RayTraceUtils;
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
|
import baritone.api.utils.RotationUtils;
|
||||||
import baritone.api.utils.input.Input;
|
import baritone.api.utils.input.Input;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
@@ -72,6 +75,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
private int ticks;
|
private int ticks;
|
||||||
private boolean paused;
|
private boolean paused;
|
||||||
private int layer;
|
private int layer;
|
||||||
|
private int numRepeats;
|
||||||
private List<IBlockState> approxPlaceable;
|
private List<IBlockState> approxPlaceable;
|
||||||
|
|
||||||
public BuilderProcess(Baritone baritone) {
|
public BuilderProcess(Baritone baritone) {
|
||||||
@@ -98,6 +102,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
this.origin = new Vec3i(x, y, z);
|
this.origin = new Vec3i(x, y, z);
|
||||||
this.paused = false;
|
this.paused = false;
|
||||||
this.layer = 0;
|
this.layer = 0;
|
||||||
|
this.numRepeats = 0;
|
||||||
this.observedCompleted = new LongOpenHashSet();
|
this.observedCompleted = new LongOpenHashSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +413,9 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
return onTick(calcFailed, isSafeToCancel);
|
return onTick(calcFailed, isSafeToCancel);
|
||||||
}
|
}
|
||||||
Vec3i repeat = Baritone.settings().buildRepeat.value;
|
Vec3i repeat = Baritone.settings().buildRepeat.value;
|
||||||
if (repeat.equals(new Vec3i(0, 0, 0))) {
|
int max = Baritone.settings().buildRepeatCount.value;
|
||||||
|
numRepeats++;
|
||||||
|
if (repeat.equals(new Vec3i(0, 0, 0)) || (max != -1 && numRepeats >= max)) {
|
||||||
logDirect("Done building");
|
logDirect("Done building");
|
||||||
onLostControl();
|
onLostControl();
|
||||||
return null;
|
return null;
|
||||||
@@ -748,6 +755,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
schematic = null;
|
schematic = null;
|
||||||
realSchematic = null;
|
realSchematic = null;
|
||||||
layer = 0;
|
layer = 0;
|
||||||
|
numRepeats = 0;
|
||||||
paused = false;
|
paused = false;
|
||||||
observedCompleted = null;
|
observedCompleted = null;
|
||||||
}
|
}
|
||||||
@@ -783,6 +791,12 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// TODO more complicated comparison logic I guess
|
// TODO more complicated comparison logic I guess
|
||||||
|
if (desired.getBlock() instanceof BlockAir && Baritone.settings().buildIgnoreBlocks.value.contains(current.getBlock())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(current.getBlock() instanceof BlockAir) && Baritone.settings().buildIgnoreExisting.value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return current.equals(desired);
|
return current.equals(desired);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import net.minecraft.client.Minecraft;
|
|||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.ChunkPos;
|
import net.minecraft.util.math.ChunkPos;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
|
||||||
@@ -42,6 +43,9 @@ public class BlockStateInterface {
|
|||||||
|
|
||||||
private final Long2ObjectMap<Chunk> loadedChunks;
|
private final Long2ObjectMap<Chunk> loadedChunks;
|
||||||
private final WorldData worldData;
|
private final WorldData worldData;
|
||||||
|
protected final IBlockReader world;
|
||||||
|
public final BlockPos.MutableBlockPos isPassableBlockPos;
|
||||||
|
public final IBlockReader access;
|
||||||
|
|
||||||
private Chunk prev = null;
|
private Chunk prev = null;
|
||||||
private CachedRegion prevCached = null;
|
private CachedRegion prevCached = null;
|
||||||
@@ -59,6 +63,7 @@ public class BlockStateInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BlockStateInterface(World world, WorldData worldData, boolean copyLoadedChunks) {
|
public BlockStateInterface(World world, WorldData worldData, boolean copyLoadedChunks) {
|
||||||
|
this.world = world;
|
||||||
this.worldData = worldData;
|
this.worldData = worldData;
|
||||||
Long2ObjectMap<Chunk> worldLoaded = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks();
|
Long2ObjectMap<Chunk> worldLoaded = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks();
|
||||||
if (copyLoadedChunks) {
|
if (copyLoadedChunks) {
|
||||||
@@ -70,6 +75,8 @@ public class BlockStateInterface {
|
|||||||
if (!Minecraft.getInstance().isCallingFromMinecraftThread()) {
|
if (!Minecraft.getInstance().isCallingFromMinecraftThread()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
this.isPassableBlockPos = new BlockPos.MutableBlockPos();
|
||||||
|
this.access = new BlockStateInterfaceAccessWrapper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean worldContainsLoadedChunk(int blockX, int blockZ) {
|
public boolean worldContainsLoadedChunk(int blockX, int blockZ) {
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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.utils;
|
||||||
|
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.fluid.IFluidState;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 11/5/2019
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("NullableProblems")
|
||||||
|
public final class BlockStateInterfaceAccessWrapper implements IBlockReader {
|
||||||
|
|
||||||
|
private final BlockStateInterface bsi;
|
||||||
|
|
||||||
|
BlockStateInterfaceAccessWrapper(BlockStateInterface bsi) {
|
||||||
|
this.bsi = bsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public TileEntity getTileEntity(BlockPos pos) {
|
||||||
|
throw new UnsupportedOperationException("getTileEntity not supported by BlockStateInterfaceAccessWrapper");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlockState getBlockState(BlockPos pos) {
|
||||||
|
// BlockStateInterface#get0(BlockPos) btfo!
|
||||||
|
return this.bsi.get0(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IFluidState getFluidState(BlockPos blockPos) {
|
||||||
|
return getBlockState(blockPos).getFluidState();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user