Merge branch '1.13.2' into 1.14.4
This commit is contained in:
@@ -21,9 +21,11 @@ import baritone.api.IBaritone;
|
||||
import baritone.api.IBaritoneProvider;
|
||||
import baritone.api.cache.IWorldScanner;
|
||||
import baritone.api.command.ICommandSystem;
|
||||
import baritone.api.schematic.ISchematicSystem;
|
||||
import baritone.command.BaritoneChatControl;
|
||||
import baritone.cache.WorldScanner;
|
||||
import baritone.command.CommandSystem;
|
||||
import baritone.utils.schematic.SchematicSystem;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -64,4 +66,9 @@ public final class BaritoneProvider implements IBaritoneProvider {
|
||||
public ICommandSystem getCommandSystem() {
|
||||
return CommandSystem.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISchematicSystem getSchematicSystem() {
|
||||
return SchematicSystem.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
59
src/main/java/baritone/cache/WorldScanner.java
vendored
59
src/main/java/baritone/cache/WorldScanner.java
vendored
@@ -27,8 +27,10 @@ import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.multiplayer.ClientChunkProvider;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.chunk.AbstractChunkProvider;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.ChunkSection;
|
||||
import net.minecraft.world.chunk.IChunk;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.IntStream;
|
||||
@@ -109,6 +111,41 @@ public enum WorldScanner implements IWorldScanner {
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int repack(IPlayerContext ctx) {
|
||||
return this.repack(ctx, 40);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int repack(IPlayerContext ctx, int range) {
|
||||
AbstractChunkProvider chunkProvider = ctx.world().getChunkProvider();
|
||||
ICachedWorld cachedWorld = ctx.worldData().getCachedWorld();
|
||||
|
||||
BetterBlockPos playerPos = ctx.playerFeet();
|
||||
|
||||
int playerChunkX = playerPos.getX() >> 4;
|
||||
int playerChunkZ = playerPos.getZ() >> 4;
|
||||
|
||||
int minX = playerChunkX - range;
|
||||
int minZ = playerChunkZ - range;
|
||||
int maxX = playerChunkX + range;
|
||||
int maxZ = playerChunkZ + range;
|
||||
|
||||
int queued = 0;
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
Chunk chunk = chunkProvider.getChunk(x, z, false);
|
||||
|
||||
if (chunk != null && !chunk.isEmpty()) {
|
||||
queued++;
|
||||
cachedWorld.queueForPacking(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return queued;
|
||||
}
|
||||
|
||||
private boolean scanChunkInto(int chunkX, int chunkZ, Chunk chunk, BlockOptionalMetaLookup filter, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY, int[] coordinateIterationOrder) {
|
||||
ChunkSection[] chunkInternalStorageArray = chunk.getSections();
|
||||
boolean foundWithinY = false;
|
||||
@@ -145,26 +182,4 @@ public enum WorldScanner implements IWorldScanner {
|
||||
}
|
||||
return foundWithinY;
|
||||
}
|
||||
|
||||
public int repack(IPlayerContext ctx) {
|
||||
ClientChunkProvider chunkProvider = (ClientChunkProvider) ctx.world().getChunkProvider();
|
||||
ICachedWorld cachedWorld = ctx.worldData().getCachedWorld();
|
||||
|
||||
BetterBlockPos playerPos = ctx.playerFeet();
|
||||
int playerChunkX = playerPos.getX() >> 4;
|
||||
int playerChunkZ = playerPos.getZ() >> 4;
|
||||
int queued = 0;
|
||||
for (int x = playerChunkX - 40; x <= playerChunkX + 40; x++) {
|
||||
for (int z = playerChunkZ - 40; z <= playerChunkZ + 40; z++) {
|
||||
Chunk chunk = chunkProvider.getChunk(x, z, null, false);
|
||||
|
||||
if (chunk != null && !chunk.isEmpty()) {
|
||||
queued++;
|
||||
cachedWorld.queueForPacking(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return queued;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,8 +316,7 @@ public class ArgConsumer implements IArgConsumer {
|
||||
try {
|
||||
return datatype.apply(this.context, original);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName());
|
||||
throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,7 +345,7 @@ public class ArgConsumer implements IArgConsumer {
|
||||
try {
|
||||
return datatype.get(this.context);
|
||||
} catch (Exception e) {
|
||||
throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName());
|
||||
throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package baritone.command.defaults;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.command.Command;
|
||||
@@ -26,11 +27,11 @@ import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.exception.CommandInvalidStateException;
|
||||
import baritone.api.command.argument.IArgConsumer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class BuildCommand extends Command {
|
||||
@@ -44,8 +45,8 @@ public class BuildCommand extends Command {
|
||||
@Override
|
||||
public void execute(String label, IArgConsumer args) throws CommandException {
|
||||
File file = args.getDatatypePost(RelativeFile.INSTANCE, schematicsDir).getAbsoluteFile();
|
||||
if (!file.getName().toLowerCase(Locale.US).endsWith(".schematic")) {
|
||||
file = new File(file.getAbsolutePath() + ".schematic");
|
||||
if (FilenameUtils.getExtension(file.getAbsolutePath()).isEmpty()) {
|
||||
file = new File(file.getAbsolutePath() + "." + Baritone.settings().schematicFallbackExtension);
|
||||
}
|
||||
BetterBlockPos origin = ctx.playerFeet();
|
||||
BetterBlockPos buildOrigin;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
private DefaultCommands() {}
|
||||
private DefaultCommands() {
|
||||
}
|
||||
|
||||
public static List<ICommand> createAll(IBaritone baritone) {
|
||||
Objects.requireNonNull(baritone);
|
||||
List<ICommand> commands = new ArrayList<>(Arrays.asList(
|
||||
new HelpCommand(baritone),
|
||||
new SetCommand(baritone),
|
||||
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 GoalCommand(baritone),
|
||||
new GotoCommand(baritone),
|
||||
new PathCommand(baritone),
|
||||
new ProcCommand(baritone),
|
||||
new VersionCommand(baritone),
|
||||
new RepackCommand(baritone),
|
||||
new BuildCommand(baritone),
|
||||
new SchematicaCommand(baritone),
|
||||
new ComeCommand(baritone),
|
||||
new AxisCommand(baritone),
|
||||
new CancelCommand(baritone),
|
||||
new ForceCancelCommand(baritone),
|
||||
new GcCommand(baritone),
|
||||
new InvertCommand(baritone),
|
||||
new TunnelCommand(baritone),
|
||||
new RenderCommand(baritone),
|
||||
new FarmCommand(baritone),
|
||||
new ChestsCommand(baritone),
|
||||
new FollowCommand(baritone),
|
||||
new ExploreFilterCommand(baritone),
|
||||
new ReloadAllCommand(baritone),
|
||||
new SaveAllCommand(baritone),
|
||||
new ExploreCommand(baritone),
|
||||
new BlacklistCommand(baritone),
|
||||
new FindCommand(baritone),
|
||||
new MineCommand(baritone),
|
||||
new ClickCommand(baritone),
|
||||
new ThisWayCommand(baritone),
|
||||
new WaypointsCommand(baritone),
|
||||
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 SelCommand(baritone)
|
||||
new HelpCommand(baritone),
|
||||
new SetCommand(baritone),
|
||||
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 GoalCommand(baritone),
|
||||
new GotoCommand(baritone),
|
||||
new PathCommand(baritone),
|
||||
new ProcCommand(baritone),
|
||||
new VersionCommand(baritone),
|
||||
new RepackCommand(baritone),
|
||||
new BuildCommand(baritone),
|
||||
new SchematicaCommand(baritone),
|
||||
new ComeCommand(baritone),
|
||||
new AxisCommand(baritone),
|
||||
new ForceCancelCommand(baritone),
|
||||
new GcCommand(baritone),
|
||||
new InvertCommand(baritone),
|
||||
new TunnelCommand(baritone),
|
||||
new RenderCommand(baritone),
|
||||
new FarmCommand(baritone),
|
||||
new ChestsCommand(baritone),
|
||||
new FollowCommand(baritone),
|
||||
new ExploreFilterCommand(baritone),
|
||||
new ReloadAllCommand(baritone),
|
||||
new SaveAllCommand(baritone),
|
||||
new ExploreCommand(baritone),
|
||||
new BlacklistCommand(baritone),
|
||||
new FindCommand(baritone),
|
||||
new MineCommand(baritone),
|
||||
new ClickCommand(baritone),
|
||||
new ThisWayCommand(baritone),
|
||||
new WaypointsCommand(baritone),
|
||||
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 SelCommand(baritone)
|
||||
));
|
||||
PauseResumeCommands prc = new PauseResumeCommands(baritone);
|
||||
ExecutionControlCommands prc = new ExecutionControlCommands(baritone);
|
||||
commands.add(prc.pauseCommand);
|
||||
commands.add(prc.resumeCommand);
|
||||
commands.add(prc.pausedCommand);
|
||||
commands.add(prc.cancelCommand);
|
||||
return Collections.unmodifiableList(commands);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
package baritone.command.defaults;
|
||||
|
||||
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.PathingCommand;
|
||||
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.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
|
||||
* REQUEST_PAUSE} as needed.
|
||||
*/
|
||||
public class PauseResumeCommands {
|
||||
public class ExecutionControlCommands {
|
||||
|
||||
Command pauseCommand;
|
||||
Command resumeCommand;
|
||||
Command pausedCommand;
|
||||
Command cancelCommand;
|
||||
|
||||
public PauseResumeCommands(IBaritone baritone) {
|
||||
public ExecutionControlCommands(IBaritone baritone) {
|
||||
// array for mutability, non-field so reflection can't touch it
|
||||
final boolean[] paused = {false};
|
||||
baritone.getPathingControlManager().registerProcess(
|
||||
@@ -64,7 +65,8 @@ public class PauseResumeCommands {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLostControl() {}
|
||||
public void onLostControl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
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();
|
||||
Goal goal = args.getDatatypePostOrNull(RelativeGoal.INSTANCE, origin);
|
||||
Goal goal = args.getDatatypePost(RelativeGoal.INSTANCE, origin);
|
||||
logDirect(String.format("Going to: %s", goal.toString()));
|
||||
baritone.getCustomGoalProcess().setGoalAndPath(goal);
|
||||
return;
|
||||
|
||||
@@ -37,6 +37,7 @@ import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -138,7 +139,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
// every block that overrides isPassable with anything more complicated than a "return true;" or "return false;"
|
||||
// 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
|
||||
return state.allowsMovement(null, BlockPos.ZERO, PathType.LAND); // workaround for future compatibility =P
|
||||
return state.allowsMovement(bsi.access, BlockPos.ZERO, PathType.LAND); // workaround for future compatibility =P
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,10 +153,18 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
* @return Whether or not the block at the specified position
|
||||
*/
|
||||
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(BlockState state) {
|
||||
static boolean fullyPassable(IPlayerContext ctx, BlockPos pos) {
|
||||
return fullyPassable(ctx.world(), pos, ctx.world().getBlockState(pos));
|
||||
}
|
||||
|
||||
static boolean fullyPassable(IBlockReader access, BlockPos pos, BlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (block instanceof AirBlock) { // early return for most common case
|
||||
return true;
|
||||
@@ -178,7 +187,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return false;
|
||||
}
|
||||
// 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, BlockState state, BlockStateInterface bsi) {
|
||||
|
||||
@@ -115,7 +115,7 @@ public class MovementParkour extends Movement {
|
||||
return;
|
||||
}
|
||||
BlockState 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)) {
|
||||
res.x = destX;
|
||||
res.y = y + 1;
|
||||
|
||||
@@ -466,7 +466,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
}
|
||||
for (int y = next.getDest().y; y <= movement.getSrc().y + 1; y++) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -491,7 +491,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
}
|
||||
// we are centered
|
||||
BlockPos headBonk = current.getSrc().subtract(current.getDirection()).up(2);
|
||||
if (MovementHelper.fullyPassable(ctx.world().getBlockState(headBonk))) {
|
||||
if (MovementHelper.fullyPassable(ctx, headBonk)) {
|
||||
return true;
|
||||
}
|
||||
// wait 0.3
|
||||
@@ -524,7 +524,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
if (x == 1) {
|
||||
chk = chk.add(current.getDirection());
|
||||
}
|
||||
if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) {
|
||||
if (!MovementHelper.fullyPassable(ctx, chk)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,14 @@ import baritone.api.pathing.goals.GoalGetToBlock;
|
||||
import baritone.api.process.IBuilderProcess;
|
||||
import baritone.api.process.PathingCommand;
|
||||
import baritone.api.process.PathingCommandType;
|
||||
import baritone.api.schematic.FillSchematic;
|
||||
import baritone.api.schematic.ISchematic;
|
||||
import baritone.api.utils.*;
|
||||
import baritone.api.schematic.IStaticSchematic;
|
||||
import baritone.api.schematic.format.ISchematicFormat;
|
||||
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.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.Movement;
|
||||
@@ -34,9 +40,8 @@ import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.utils.BaritoneProcessHelper;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.PathingCommandContext;
|
||||
import baritone.utils.schematic.FillSchematic;
|
||||
import baritone.utils.schematic.MapArtSchematic;
|
||||
import baritone.utils.schematic.Schematic;
|
||||
import baritone.utils.schematic.SchematicSystem;
|
||||
import baritone.utils.schematic.schematica.SchematicaHelper;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import net.minecraft.block.AirBlock;
|
||||
@@ -57,7 +62,6 @@ import net.minecraft.util.math.shapes.VoxelShape;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import static baritone.api.pathing.movement.ActionCosts.COST_INF;
|
||||
@@ -73,6 +77,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
||||
private int ticks;
|
||||
private boolean paused;
|
||||
private int layer;
|
||||
private int numRepeats;
|
||||
private List<BlockState> approxPlaceable;
|
||||
|
||||
public BuilderProcess(Baritone baritone) {
|
||||
@@ -99,6 +104,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
||||
this.origin = new Vec3i(x, y, z);
|
||||
this.paused = false;
|
||||
this.layer = 0;
|
||||
this.numRepeats = 0;
|
||||
this.observedCompleted = new LongOpenHashSet();
|
||||
}
|
||||
|
||||
@@ -117,27 +123,38 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
||||
|
||||
@Override
|
||||
public boolean build(String name, File schematic, Vec3i origin) {
|
||||
CompoundNBT tag;
|
||||
try (FileInputStream fileIn = new FileInputStream(schematic)) {
|
||||
tag = CompressedStreamTools.readCompressed(fileIn);
|
||||
} catch (IOException e) {
|
||||
Optional<ISchematicFormat> format = SchematicSystem.INSTANCE.getByFile(schematic);
|
||||
if (!format.isPresent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ISchematic parsed;
|
||||
try {
|
||||
parsed = format.get().parse(new FileInputStream(schematic));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
//noinspection ConstantConditions
|
||||
if (tag == null) {
|
||||
return false;
|
||||
|
||||
if (Baritone.settings().mapArtMode.value) {
|
||||
parsed = new MapArtSchematic((IStaticSchematic) parsed);
|
||||
}
|
||||
build(name, parse(tag), origin);
|
||||
|
||||
build(name, parsed, origin);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildOpenSchematic() {
|
||||
if (SchematicaHelper.isSchematicaPresent()) {
|
||||
Optional<Tuple<ISchematic, BlockPos>> schematic = SchematicaHelper.getOpenSchematic();
|
||||
Optional<Tuple<IStaticSchematic, BlockPos>> schematic = SchematicaHelper.getOpenSchematic();
|
||||
if (schematic.isPresent()) {
|
||||
this.build(schematic.get().getA().toString(), schematic.get().getA(), schematic.get().getB());
|
||||
IStaticSchematic s = schematic.get().getA();
|
||||
this.build(
|
||||
schematic.get().getA().toString(),
|
||||
Baritone.settings().mapArtMode.value ? new MapArtSchematic(s) : s,
|
||||
schematic.get().getB()
|
||||
);
|
||||
} else {
|
||||
logDirect("No schematic currently open");
|
||||
}
|
||||
@@ -159,10 +176,6 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
||||
return new ArrayList<>(approxPlaceable);
|
||||
}
|
||||
|
||||
private static ISchematic parse(CompoundNBT schematic) {
|
||||
return Baritone.settings().mapArtMode.value ? new MapArtSchematic(schematic) : new Schematic(schematic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return schematic != null;
|
||||
@@ -407,7 +420,9 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
||||
return onTick(calcFailed, isSafeToCancel);
|
||||
}
|
||||
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");
|
||||
onLostControl();
|
||||
return null;
|
||||
@@ -747,6 +762,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
||||
schematic = null;
|
||||
realSchematic = null;
|
||||
layer = 0;
|
||||
numRepeats = 0;
|
||||
paused = false;
|
||||
observedCompleted = null;
|
||||
}
|
||||
@@ -782,6 +798,12 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
||||
return true;
|
||||
}
|
||||
// TODO more complicated comparison logic I guess
|
||||
if (desired.getBlock() instanceof AirBlock && Baritone.settings().buildIgnoreBlocks.value.contains(current.getBlock())) {
|
||||
return true;
|
||||
}
|
||||
if (!(current.getBlock() instanceof AirBlock) && Baritone.settings().buildIgnoreExisting.value) {
|
||||
return true;
|
||||
}
|
||||
return current.equals(desired);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,13 +31,13 @@ import net.minecraft.client.settings.AmbientOcclusionStatus;
|
||||
import net.minecraft.client.settings.CloudOption;
|
||||
import net.minecraft.client.settings.ParticleStatus;
|
||||
import net.minecraft.client.tutorial.TutorialSteps;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.server.integrated.IntegratedServer;
|
||||
import net.minecraft.util.HTTPUtil;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.GameType;
|
||||
import net.minecraft.world.WorldSettings;
|
||||
import net.minecraft.world.WorldType;
|
||||
import net.minecraft.world.*;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -95,7 +95,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
||||
if (mc.currentScreen instanceof MainMenuScreen) {
|
||||
System.out.println("Beginning Baritone automatic test routine");
|
||||
mc.displayGuiScreen(null);
|
||||
WorldSettings worldsettings = new WorldSettings(TEST_SEED, GameType.getByName("survival"), true, false, WorldType.DEFAULT);
|
||||
WorldSettings worldsettings = new WorldSettings(TEST_SEED, GameType.SURVIVAL, true, false, WorldType.DEFAULT);
|
||||
mc.launchIntegratedServer("BaritoneAutoTest", "BaritoneAutoTest", worldsettings);
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
||||
// If the integrated server is launched and the world has initialized, set the spawn point
|
||||
// to our defined starting position
|
||||
if (server != null && server.getWorld(DimensionType.OVERWORLD) != null) {
|
||||
server.setDifficultyForAllWorlds(Difficulty.PEACEFUL, true);
|
||||
if (mc.player == null) {
|
||||
server.execute(() -> {
|
||||
server.getWorld(DimensionType.OVERWORLD).setSpawnPoint(STARTING_POSITION);
|
||||
@@ -113,6 +114,17 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
||||
throw new IllegalStateException(result + "");
|
||||
}
|
||||
});
|
||||
for (final ServerWorld world : mc.getIntegratedServer().getWorlds()) {
|
||||
// If the world has initialized, set the spawn point to our defined starting position
|
||||
if (world != null) {
|
||||
// I would rather do this than try to mess with poz
|
||||
CompoundNBT nbt = world.getGameRules().write();
|
||||
nbt.putString("spawnRadius", "0");
|
||||
world.getGameRules().read(nbt);
|
||||
|
||||
world.setSpawnPoint(STARTING_POSITION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +133,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
||||
// Force the integrated server to share the world to LAN so that
|
||||
// the ingame pause menu gui doesn't actually pause our game
|
||||
if (mc.isSingleplayer() && !mc.getIntegratedServer().getPublic()) {
|
||||
mc.getIntegratedServer().shareToLAN(GameType.getByName("survival"), false, HTTPUtil.getSuitableLanPort());
|
||||
mc.getIntegratedServer().shareToLAN(GameType.SURVIVAL, false, HTTPUtil.getSuitableLanPort());
|
||||
}
|
||||
|
||||
// For the first 200 ticks, wait for the world to generate
|
||||
@@ -163,5 +175,6 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
||||
}
|
||||
}
|
||||
|
||||
private BaritoneAutoTest() {}
|
||||
private BaritoneAutoTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientChunkProvider;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.ChunkSection;
|
||||
@@ -42,6 +43,9 @@ public class BlockStateInterface {
|
||||
|
||||
private final ClientChunkProvider provider;
|
||||
private final WorldData worldData;
|
||||
protected final IBlockReader world;
|
||||
public final BlockPos.MutableBlockPos isPassableBlockPos;
|
||||
public final IBlockReader access;
|
||||
|
||||
private Chunk prev = null;
|
||||
private CachedRegion prevCached = null;
|
||||
@@ -59,6 +63,7 @@ public class BlockStateInterface {
|
||||
}
|
||||
|
||||
public BlockStateInterface(World world, WorldData worldData, boolean copyLoadedChunks) {
|
||||
this.world = world;
|
||||
this.worldData = worldData;
|
||||
if (copyLoadedChunks) {
|
||||
this.provider = ((IClientChunkProvider) world.getChunkProvider()).createThreadSafeCopy();
|
||||
@@ -69,6 +74,8 @@ public class BlockStateInterface {
|
||||
if (!Minecraft.getInstance().isOnExecutionThread()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
this.isPassableBlockPos = new BlockPos.MutableBlockPos();
|
||||
this.access = new BlockStateInterfaceAccessWrapper(this);
|
||||
}
|
||||
|
||||
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.BlockState;
|
||||
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 BlockState 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();
|
||||
}
|
||||
}
|
||||
@@ -19,23 +19,32 @@ package baritone.utils.schematic;
|
||||
|
||||
import net.minecraft.block.AirBlock;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import baritone.api.schematic.IStaticSchematic;
|
||||
import baritone.api.schematic.MaskSchematic;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class MapArtSchematic extends Schematic {
|
||||
public class MapArtSchematic extends MaskSchematic {
|
||||
|
||||
private final int[][] heightMap;
|
||||
|
||||
public MapArtSchematic(CompoundNBT schematic) {
|
||||
public MapArtSchematic(IStaticSchematic schematic) {
|
||||
super(schematic);
|
||||
heightMap = new int[widthX][lengthZ];
|
||||
this.heightMap = generateHeightMap(schematic);
|
||||
}
|
||||
|
||||
for (int x = 0; x < widthX; x++) {
|
||||
for (int z = 0; z < lengthZ; z++) {
|
||||
BlockState[] column = states[x][z];
|
||||
@Override
|
||||
protected boolean partOfMask(int x, int y, int z, BlockState currentState) {
|
||||
return y >= this.heightMap[x][z];
|
||||
}
|
||||
|
||||
private static int[][] generateHeightMap(IStaticSchematic schematic) {
|
||||
int[][] heightMap = new int[schematic.widthX()][schematic.lengthZ()];
|
||||
|
||||
for (int x = 0; x < schematic.widthX(); x++) {
|
||||
for (int z = 0; z < schematic.lengthZ(); z++) {
|
||||
BlockState[] column = schematic.getColumn(x, z);
|
||||
OptionalInt lowestBlockY = lastIndexMatching(column, state -> !(state.getBlock() instanceof AirBlock));
|
||||
if (lowestBlockY.isPresent()) {
|
||||
heightMap[x][z] = lowestBlockY.getAsInt();
|
||||
@@ -44,9 +53,9 @@ public class MapArtSchematic extends Schematic {
|
||||
System.out.println("Letting it be whatever");
|
||||
heightMap[x][z] = 256;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return heightMap;
|
||||
}
|
||||
|
||||
private static <T> OptionalInt lastIndexMatching(T[] arr, Predicate<? super T> predicate) {
|
||||
@@ -57,10 +66,4 @@ public class MapArtSchematic extends Schematic {
|
||||
}
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inSchematic(int x, int y, int z, BlockState currentState) {
|
||||
// in map art, we only care about coordinates in or above the art
|
||||
return super.inSchematic(x, y, z, currentState) && y >= heightMap[x][z];
|
||||
}
|
||||
}
|
||||
|
||||
51
src/main/java/baritone/utils/schematic/SchematicSystem.java
Normal file
51
src/main/java/baritone/utils/schematic/SchematicSystem.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.schematic;
|
||||
|
||||
import baritone.api.command.registry.Registry;
|
||||
import baritone.api.schematic.ISchematicSystem;
|
||||
import baritone.api.schematic.format.ISchematicFormat;
|
||||
import baritone.utils.schematic.format.DefaultSchematicFormats;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 12/24/2019
|
||||
*/
|
||||
public enum SchematicSystem implements ISchematicSystem {
|
||||
INSTANCE;
|
||||
|
||||
private final Registry<ISchematicFormat> registry = new Registry<>();
|
||||
|
||||
SchematicSystem() {
|
||||
Arrays.stream(DefaultSchematicFormats.values()).forEach(this.registry::register);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry<ISchematicFormat> getRegistry() {
|
||||
return this.registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ISchematicFormat> getByFile(File file) {
|
||||
return this.registry.stream().filter(format -> format.isFileType(file)).findFirst();
|
||||
}
|
||||
}
|
||||
@@ -17,42 +17,34 @@
|
||||
|
||||
package baritone.utils.schematic;
|
||||
|
||||
import baritone.api.schematic.ISchematic;
|
||||
import baritone.api.schematic.AbstractSchematic;
|
||||
import baritone.api.schematic.IStaticSchematic;
|
||||
import net.minecraft.block.BlockState;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FillSchematic implements ISchematic {
|
||||
/**
|
||||
* Default implementation of {@link IStaticSchematic}
|
||||
*
|
||||
* @author Brady
|
||||
* @since 12/23/2019
|
||||
*/
|
||||
public class StaticSchematic extends AbstractSchematic implements IStaticSchematic {
|
||||
|
||||
private final int widthX;
|
||||
private final int heightY;
|
||||
private final int lengthZ;
|
||||
private final BlockState state;
|
||||
|
||||
public FillSchematic(int widthX, int heightY, int lengthZ, BlockState state) {
|
||||
this.widthX = widthX;
|
||||
this.heightY = heightY;
|
||||
this.lengthZ = lengthZ;
|
||||
this.state = state;
|
||||
}
|
||||
protected BlockState[][][] states;
|
||||
|
||||
@Override
|
||||
public BlockState desiredState(int x, int y, int z, BlockState current, List<BlockState> approxPlaceable) {
|
||||
return state;
|
||||
return this.states[x][z][y];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int widthX() {
|
||||
return widthX;
|
||||
public BlockState getDirect(int x, int y, int z) {
|
||||
return this.states[x][z][y];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int heightY() {
|
||||
return heightY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lengthZ() {
|
||||
return lengthZ;
|
||||
public BlockState[] getColumn(int x, int z) {
|
||||
return this.states[x][z];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.schematic.format;
|
||||
|
||||
import baritone.api.schematic.IStaticSchematic;
|
||||
import baritone.api.schematic.format.ISchematicFormat;
|
||||
import baritone.utils.schematic.format.defaults.MCEditSchematic;
|
||||
import baritone.utils.schematic.format.defaults.SpongeSchematic;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Default implementations of {@link ISchematicFormat}
|
||||
*
|
||||
* @author Brady
|
||||
* @since 12/13/2019
|
||||
*/
|
||||
public enum DefaultSchematicFormats implements ISchematicFormat {
|
||||
|
||||
/**
|
||||
* The MCEdit schematic specification. Commonly denoted by the ".schematic" file extension.
|
||||
*/
|
||||
MCEDIT("schematic") {
|
||||
|
||||
@Override
|
||||
public IStaticSchematic parse(InputStream input) throws IOException {
|
||||
return new MCEditSchematic(CompressedStreamTools.readCompressed(input));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The SpongePowered Schematic Specification. Commonly denoted by the ".schem" file extension.
|
||||
*
|
||||
* @see <a href="https://github.com/SpongePowered/Schematic-Specification">Sponge Schematic Specification</a>
|
||||
*/
|
||||
SPONGE("schem") {
|
||||
|
||||
@Override
|
||||
public IStaticSchematic parse(InputStream input) throws IOException {
|
||||
CompoundNBT nbt = CompressedStreamTools.readCompressed(input);
|
||||
int version = nbt.getInt("Version");
|
||||
switch (version) {
|
||||
case 1:
|
||||
case 2:
|
||||
return new SpongeSchematic(nbt);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unsupported Version of a Sponge Schematic");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final String extension;
|
||||
|
||||
DefaultSchematicFormats(String extension) {
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFileType(File file) {
|
||||
return this.extension.equalsIgnoreCase(FilenameUtils.getExtension(file.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
@@ -15,34 +15,35 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.utils.schematic;
|
||||
package baritone.utils.schematic.format.defaults;
|
||||
|
||||
import baritone.api.schematic.ISchematic;
|
||||
import baritone.utils.schematic.StaticSchematic;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.datafix.fixes.ItemIntIDToString;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.List;
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 12/27/2019
|
||||
*/
|
||||
public final class MCEditSchematic extends StaticSchematic {
|
||||
|
||||
public class Schematic implements ISchematic {
|
||||
|
||||
public final int widthX;
|
||||
public final int heightY;
|
||||
public final int lengthZ;
|
||||
protected final BlockState[][][] states;
|
||||
|
||||
public Schematic(CompoundNBT schematic) {
|
||||
/*String type = schematic.getString("Materials");
|
||||
public MCEditSchematic(CompoundNBT schematic) {
|
||||
String type = schematic.getString("Materials");
|
||||
if (!type.equals("Alpha")) {
|
||||
throw new IllegalStateException("bad schematic " + type);
|
||||
}
|
||||
widthX = schematic.getInteger("Width");
|
||||
heightY = schematic.getInteger("Height");
|
||||
lengthZ = schematic.getInteger("Length");
|
||||
this.x = schematic.getInt("Width");
|
||||
this.y = schematic.getInt("Height");
|
||||
this.z = schematic.getInt("Length");
|
||||
byte[] blocks = schematic.getByteArray("Blocks");
|
||||
byte[] metadata = schematic.getByteArray("Data");
|
||||
// byte[] metadata = schematic.getByteArray("Data");
|
||||
|
||||
byte[] additional = null;
|
||||
if (schematic.hasKey("AddBlocks")) {
|
||||
if (schematic.contains("AddBlocks")) {
|
||||
byte[] addBlocks = schematic.getByteArray("AddBlocks");
|
||||
additional = new byte[addBlocks.length * 2];
|
||||
for (int i = 0; i < addBlocks.length; i++) {
|
||||
@@ -50,43 +51,23 @@ public class Schematic implements ISchematic {
|
||||
additional[i * 2 + 1] = (byte) ((addBlocks[i] >> 0) & 0xF); // upper nibble
|
||||
}
|
||||
}
|
||||
states = new BlockState[widthX][lengthZ][heightY];
|
||||
for (int y = 0; y < heightY; y++) {
|
||||
for (int z = 0; z < lengthZ; z++) {
|
||||
for (int x = 0; x < widthX; x++) {
|
||||
int blockInd = (y * lengthZ + z) * widthX + x;
|
||||
this.states = new BlockState[this.x][this.z][this.y];
|
||||
for (int y = 0; y < this.y; y++) {
|
||||
for (int z = 0; z < this.z; z++) {
|
||||
for (int x = 0; x < this.x; x++) {
|
||||
int blockInd = (y * this.z + z) * this.x + x;
|
||||
|
||||
int blockID = blocks[blockInd] & 0xFF;
|
||||
if (additional != null) {
|
||||
// additional is 0 through 15 inclusive since it's & 0xF above
|
||||
blockID |= additional[blockInd] << 8;
|
||||
}
|
||||
Block block = Block.REGISTRY.getObjectById(blockID);
|
||||
int meta = metadata[blockInd] & 0xFF;
|
||||
states[x][z][y] = block.getStateFromMeta(meta);
|
||||
Block block = Registry.BLOCK.getOrDefault(ResourceLocation.tryCreate(ItemIntIDToString.getItem(blockID)));
|
||||
// int meta = metadata[blockInd] & 0xFF;
|
||||
// this.states[x][z][y] = block.getStateFromMeta(meta);
|
||||
this.states[x][z][y] = block.getDefaultState();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
throw new UnsupportedOperationException("1.13 be like: numeric IDs btfo");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState desiredState(int x, int y, int z, BlockState current, List<BlockState> approxPlaceable) {
|
||||
return states[x][z][y];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int widthX() {
|
||||
return widthX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int heightY() {
|
||||
return heightY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lengthZ() {
|
||||
return lengthZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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.schematic.format.defaults;
|
||||
|
||||
import baritone.utils.schematic.StaticSchematic;
|
||||
import baritone.utils.type.VarInt;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.state.IProperty;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 12/27/2019
|
||||
*/
|
||||
public final class SpongeSchematic extends StaticSchematic {
|
||||
|
||||
public SpongeSchematic(CompoundNBT nbt) {
|
||||
this.x = nbt.getInt("Width");
|
||||
this.y = nbt.getInt("Height");
|
||||
this.z = nbt.getInt("Length");
|
||||
this.states = new BlockState[this.x][this.z][this.y];
|
||||
|
||||
Int2ObjectArrayMap<BlockState> palette = new Int2ObjectArrayMap<>();
|
||||
CompoundNBT paletteTag = nbt.getCompound("Palette");
|
||||
for (String tag : paletteTag.keySet()) {
|
||||
int index = paletteTag.getInt(tag);
|
||||
|
||||
SerializedBlockState serializedState = SerializedBlockState.getFromString(tag);
|
||||
if (serializedState == null) {
|
||||
throw new IllegalArgumentException("Unable to parse palette tag");
|
||||
}
|
||||
|
||||
BlockState state = serializedState.deserialize();
|
||||
if (state == null) {
|
||||
throw new IllegalArgumentException("Unable to deserialize palette tag");
|
||||
}
|
||||
|
||||
palette.put(index, state);
|
||||
}
|
||||
|
||||
// BlockData is stored as an NBT byte[], however, the actual data that is represented is a varint[]
|
||||
byte[] rawBlockData = nbt.getByteArray("BlockData");
|
||||
int[] blockData = new int[this.x * this.y * this.z];
|
||||
int offset = 0;
|
||||
for (int i = 0; i < blockData.length; i++) {
|
||||
if (offset >= rawBlockData.length) {
|
||||
throw new IllegalArgumentException("No remaining bytes in BlockData for complete schematic");
|
||||
}
|
||||
|
||||
VarInt varInt = VarInt.read(rawBlockData, offset);
|
||||
blockData[i] = varInt.getValue();
|
||||
offset += varInt.getSize();
|
||||
}
|
||||
|
||||
for (int y = 0; y < this.y; y++) {
|
||||
for (int z = 0; z < this.z; z++) {
|
||||
for (int x = 0; x < this.x; x++) {
|
||||
int index = (y * this.z + z) * this.x + x;
|
||||
BlockState state = palette.get(blockData[index]);
|
||||
if (state == null) {
|
||||
throw new IllegalArgumentException("Invalid Palette Index " + index);
|
||||
}
|
||||
|
||||
this.states[x][z][y] = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SerializedBlockState {
|
||||
|
||||
private static final Pattern REGEX = Pattern.compile("(?<location>(\\w+:)?\\w+)(\\[(?<properties>(\\w+=\\w+,?)+)])?");
|
||||
|
||||
private final ResourceLocation resourceLocation;
|
||||
private final Map<String, String> properties;
|
||||
private BlockState blockState;
|
||||
|
||||
private SerializedBlockState(ResourceLocation resourceLocation, Map<String, String> properties) {
|
||||
this.resourceLocation = resourceLocation;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
private BlockState deserialize() {
|
||||
if (this.blockState == null) {
|
||||
Block block = Registry.BLOCK.getOrDefault(this.resourceLocation);
|
||||
this.blockState = block.getDefaultState();
|
||||
|
||||
this.properties.keySet().stream().sorted(String::compareTo).forEachOrdered(key -> {
|
||||
IProperty<?> property = block.getStateContainer().getProperty(key);
|
||||
if (property != null) {
|
||||
this.blockState = setPropertyValue(this.blockState, property, this.properties.get(key));
|
||||
}
|
||||
});
|
||||
}
|
||||
return this.blockState;
|
||||
}
|
||||
|
||||
private static SerializedBlockState getFromString(String s) {
|
||||
Matcher m = REGEX.matcher(s);
|
||||
if (!m.matches()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
String location = m.group("location");
|
||||
String properties = m.group("properties");
|
||||
|
||||
ResourceLocation resourceLocation = new ResourceLocation(location);
|
||||
Map<String, String> propertiesMap = new HashMap<>();
|
||||
if (properties != null) {
|
||||
for (String property : properties.split(",")) {
|
||||
String[] split = property.split("=");
|
||||
propertiesMap.put(split[0], split[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return new SerializedBlockState(resourceLocation, propertiesMap);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends Comparable<T>> BlockState setPropertyValue(BlockState state, IProperty<T> property, String value) {
|
||||
Optional<T> parsed = property.parseValue(value);
|
||||
if (parsed.isPresent()) {
|
||||
return state.with(property, parsed.get());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid value for property " + property);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,14 +17,14 @@
|
||||
|
||||
package baritone.utils.schematic.schematica;
|
||||
|
||||
import baritone.api.schematic.ISchematic;
|
||||
import baritone.api.schematic.IStaticSchematic;
|
||||
import com.github.lunatrius.schematica.client.world.SchematicWorld;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class SchematicAdapter implements ISchematic {
|
||||
public final class SchematicAdapter implements IStaticSchematic {
|
||||
|
||||
private final SchematicWorld schematic;
|
||||
|
||||
@@ -34,7 +34,12 @@ public final class SchematicAdapter implements ISchematic {
|
||||
|
||||
@Override
|
||||
public BlockState desiredState(int x, int y, int z, BlockState current, List<BlockState> approxPlaceable) {
|
||||
return schematic.getSchematic().getBlockState(new BlockPos(x, y, z));
|
||||
return this.getDirect(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getDirect(int x, int y, int z) {
|
||||
return this.schematic.getSchematic().getBlockState(new BlockPos(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
package baritone.utils.schematic.schematica;
|
||||
|
||||
import baritone.api.schematic.ISchematic;
|
||||
import baritone.api.schematic.IStaticSchematic;
|
||||
import com.github.lunatrius.schematica.Schematica;
|
||||
import com.github.lunatrius.schematica.proxy.ClientProxy;
|
||||
import net.minecraft.util.Tuple;
|
||||
@@ -37,7 +37,7 @@ public enum SchematicaHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<Tuple<ISchematic, BlockPos>> getOpenSchematic() {
|
||||
public static Optional<Tuple<IStaticSchematic, BlockPos>> getOpenSchematic() {
|
||||
return Optional.ofNullable(ClientProxy.schematic)
|
||||
.map(world -> new Tuple<>(new SchematicAdapter(world), world.position));
|
||||
}
|
||||
|
||||
95
src/main/java/baritone/utils/type/VarInt.java
Normal file
95
src/main/java/baritone/utils/type/VarInt.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.type;
|
||||
|
||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
||||
import it.unimi.dsi.fastutil.bytes.ByteList;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 12/19/2019
|
||||
*/
|
||||
public final class VarInt {
|
||||
|
||||
private final int value;
|
||||
private final byte[] serialized;
|
||||
private final int size;
|
||||
|
||||
public VarInt(int value) {
|
||||
this.value = value;
|
||||
this.serialized = serialize0(this.value);
|
||||
this.size = this.serialized.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The integer value that is represented by this {@link VarInt}.
|
||||
*/
|
||||
public final int getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The size of this {@link VarInt}, in bytes, once serialized.
|
||||
*/
|
||||
public final int getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public final byte[] serialize() {
|
||||
return this.serialized;
|
||||
}
|
||||
|
||||
private static byte[] serialize0(int valueIn) {
|
||||
ByteList bytes = new ByteArrayList();
|
||||
|
||||
int value = valueIn;
|
||||
while ((value & 0x80) != 0) {
|
||||
bytes.add((byte) (value & 0x7F | 0x80));
|
||||
value >>>= 7;
|
||||
}
|
||||
bytes.add((byte) (value & 0xFF));
|
||||
|
||||
return bytes.toByteArray();
|
||||
}
|
||||
|
||||
public static VarInt read(byte[] bytes) {
|
||||
return read(bytes, 0);
|
||||
}
|
||||
|
||||
public static VarInt read(byte[] bytes, int start) {
|
||||
int value = 0;
|
||||
int size = 0;
|
||||
int index = start;
|
||||
|
||||
while (true) {
|
||||
byte b = bytes[index++];
|
||||
value |= (b & 0x7F) << size++ * 7;
|
||||
|
||||
if (size > 5) {
|
||||
throw new IllegalArgumentException("VarInt size cannot exceed 5 bytes");
|
||||
}
|
||||
|
||||
// Most significant bit denotes another byte is to be read.
|
||||
if ((b & 0x80) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new VarInt(value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user