Compare commits

..

52 Commits

Author SHA1 Message Date
Leijurv
760ac5dd8f v1.4.4 2020-01-04 21:58:55 -08:00
Brady
92966dc57c Merge branch '1.13.2' into 1.14.4 2019-12-31 21:57:55 -06:00
Brady
e3d3407de5 Remove normalizations from BlockOptionalMeta 2019-12-31 19:44:44 -06:00
Brady
f3d860e8fa Merge branch 'master' into 1.13.2 2019-12-31 19:40:14 -06:00
Brady
adff391e45 Merge branch 'schematic-formats' 2019-12-31 18:25:21 -06:00
Brady
4a05837b01 Requested changes 2019-12-31 17:44:20 -06:00
Leijurv
1edd7126fd Merge branch 'master' into 1.13.2 2019-12-31 15:44:03 -08:00
Leijurv
a0014fda12 Merge pull request #1216 from FTC55/master
Fixed a rather obnoxious bug that would require a full restart of the client.
2019-12-31 15:35:01 -08:00
FTC55
04190af340 ...more than I thought. Autoreformatted file x2 2019-12-31 19:45:08 +01:00
FTC55
4b10904b97 Git missed some changes. Autoreformatted files. 2019-12-31 19:43:54 +01:00
FTC55
bbb25acff3 Fixed the bug, merged CancelCommand into ExecutionControlCommands 2019-12-31 19:31:30 +01:00
Brady
fcfa022232 Clean up BlockOptionalMeta comment and add behavioral clarification 2019-12-30 02:27:20 -06:00
Brady
220ee30d35 Appease Codacy 2019-12-27 21:28:05 -06:00
Brady
812bc0d8c4 Remove redundant parser layer 2019-12-27 01:14:31 -06:00
Brady
d712839c25 Make Schematica respect mapArtMode setting 2019-12-25 01:35:10 -06:00
Brady
eee705b371 Schematic Format API support 2019-12-24 17:20:00 -06:00
Brady
77bdf6e444 Fix MapSchematic 2019-12-23 18:05:50 -06:00
Brady
0a858c040c Working 2019-12-19 22:15:14 -06:00
Brady
eea5b69b6c Utilize new FillSchematic 2019-12-19 12:03:02 -06:00
Brady
6759917a2f Additional clean up 2019-12-19 11:58:47 -06:00
Brady
aa3bd80ab2 Clean ups 2019-12-19 11:40:38 -06:00
Brady
ea8d7fb3b9 Improve file extension fallback mechanism 2019-12-18 15:19:58 -06:00
Brady
b4ddf38116 Check if state is null 2019-12-18 10:27:34 -06:00
Brady
5c9f028103 Initial sponge support 2019-12-18 10:24:43 -06:00
Leijurv
937d4cc884 whoops 2019-12-13 20:46:12 -08:00
Leijurv
2c3e1f4232 builder stuff, fixes #1059 2019-12-13 20:09:04 -08:00
Leijurv
ddc681fe77 build repeat count 2019-11-24 11:11:28 -08:00
Leijurv
2b71b31cfa Merge pull request #1087 from cabaletta/ispassable-crash-fix
Fix isPassable crash
2019-11-10 22:52:29 -08:00
Leijurv
ed144e995b apparently this usage of > was an invalid javadoc command lol 2019-11-10 14:04:27 -08:00
Brady
7e3a2d3c0a Create a BlockStateInterface specialized IBlockAccess wrapper 2019-11-05 18:17:10 -06:00
Leijurv
152285043d Update USAGE.md 2019-11-05 11:50:27 -08:00
Leijurv
ce52201e45 Merge pull request #1097 from greg904/fix-goto-errmsg
Remove error message when running goto with less than 3 args
2019-10-29 21:33:27 -07:00
Leijurv
45ea776090 Update README.md 2019-10-28 10:47:20 -07:00
Leijurv
2ae16d8bb1 configurable block reach distance 2019-10-26 16:01:08 -07:00
Greg Depoire--Ferrer
23fc6c8b49 Add a space between sentences in error message 2019-10-25 14:49:57 +02:00
Greg Depoire--Ferrer
0db4b193e1 Remove hack, add comment, don't use default when arg is required 2019-10-25 14:49:08 +02:00
Greg Depoire--Ferrer
82d520d808 Don't print invalid type error to stderr 2019-10-25 14:42:36 +02:00
Brady
5201d39adf Retain old method signature 2019-10-24 15:20:23 -05:00
Brady
f02c33d95a Fix improper tick count incrementation 2019-10-23 17:47:20 -05:00
Brady
43ab4f7d3b Fix isPassable crash 2019-10-22 15:58:10 -05:00
Leijurv
a57668bd15 Merge pull request #1073 from 0-x-2-2/1.13.2
Merged master into 1.13.2 branch. 😎
2019-10-17 13:54:06 -07:00
0x22
a324b58f55 Merged master into 1.13.2 branch. 😎 2019-10-17 16:01:35 -04:00
Leijurv
6341f9fcb4 Merge pull request #1072 from 0-x-2-2/disable-autotest-mob-spawning
Disable harmful mob spawning in Travis auto test.
2019-10-17 12:05:24 -07:00
0x22
66ffd1e0d9 Disable harmful mob spawning in Travis auto test. 2019-10-17 14:35:28 -04:00
Leijurv
e65c854e6a Update USAGE.md 2019-10-15 11:25:35 -07:00
Brady
4eca960a4c Specify range in IWorldScanner#repack 2019-10-14 15:45:41 -05:00
Leijurv
214225c08d v1.4.3 2019-10-13 22:53:05 -07:00
Leijurv
05b5894348 a much better way to deal with this 2019-10-13 10:53:25 -07:00
Leijurv
69bceb43f8 Update USAGE.md 2019-10-12 13:07:12 -07:00
Leijurv
6a8807b0fa documentation stuff 2019-10-12 10:43:01 -07:00
Leijurv
105c7d438a v1.3.5 2019-10-11 17:29:27 -07:00
Leijurv
e49549117b v1.2.10 2019-10-11 17:08:28 -07:00
46 changed files with 1017 additions and 469 deletions

View File

@@ -19,7 +19,7 @@
![Lines of Code](https://tokei.rs/b1/github/cabaletta/baritone?category=code)
[![GitHub contributors](https://img.shields.io/github/contributors/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/graphs/contributors/)
[![GitHub commits](https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg)](https://github.com/cabaletta/baritone/commit/)
[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.8%20/%20v1.3.4%20/%20v1.4.1-brightgreen.svg)](https://impactclient.net/)
[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.10%20/%20v1.3.5%20/%20v1.4.3-brightgreen.svg)](https://impactclient.net/)
[![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg)](https://github.com/fr1kin/ForgeHax/)
[![Aristois add-on integration](https://img.shields.io/badge/Aristois%20add--on%20integration-v1.3.4%20/%20v1.4.1-green.svg)](https://gitlab.com/emc-mods-indrit/baritone_api)
[![WWE integration](https://img.shields.io/badge/WWE%20%22integration%22-master%3F-green.svg)](https://wweclient.com/)

View File

@@ -8,11 +8,23 @@ Baritone commands can also by default be typed in the chatbox. However if you ma
To disable direct chat control (with no prefix), turn off the `chatControl` setting. To disable chat control with the `#` prefix, turn off the `prefixControl` setting. In Impact, `.b` cannot be disabled. Be careful that you don't leave yourself with all control methods disabled (if you do, reset your settings by deleting the file `minecraft/baritone/settings.txt` and relaunching).
# For Baritone 1.2.10+, 1.3.5+, 1.4.2+
Lots of the commands have changed, BUT `#help` is improved vastly (its clickable! commands have tab completion! oh my!).
Try `#help` I promise it won't just send you back here =)
"wtf where is cleararea" -> look at `#help sel`
"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
# Commands
**All** of these commands may need a prefix before them, as above ^.
`help` for (rudimentary) help. You can see what it says [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java#L47).
`help`
To toggle a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `primaryTimeoutMS 250`). It's case insensitive. To reset a setting to its default value, say `acceptableThrowawayItems reset`. To reset all settings, say `reset`. To see all settings that have been modified from their default values, say `modified`.
@@ -38,12 +50,6 @@ Some common examples:
- `version` to get the version of Baritone you're running
- `damn` daniel
New commands:
- `sel` to manage selections
- some others
For the rest of the commands, you can take a look at the code [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java).
All the settings and documentation are <a href="https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/Settings.java">here</a>. If you find HTML easier to read than Javadoc, you can look <a href="https://baritone.leijurv.com/baritone/api/Settings.html#field.detail">here</a>.

View File

@@ -16,11 +16,10 @@
*/
group 'baritone'
version '1.4.2'
version '1.4.4'
buildscript {
repositories {
jcenter()
maven {
name = 'forge'
url = 'http://files.minecraftforge.net/maven'
@@ -29,6 +28,7 @@ buildscript {
name = 'impactdevelopment-repo'
url = 'https://impactdevelopment.github.io/maven/'
}
jcenter()
}
dependencies {

View File

@@ -21,6 +21,7 @@ import baritone.api.cache.IWorldScanner;
import baritone.api.command.ICommand;
import baritone.api.command.ICommandSystem;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import baritone.api.schematic.ISchematicSystem;
import java.util.List;
import java.util.Objects;
@@ -82,4 +83,9 @@ public interface IBaritoneProvider {
* @return The {@link ICommandSystem} instance.
*/
ICommandSystem getCommandSystem();
/**
* @return The {@link ISchematicSystem} instance.
*/
ISchematicSystem getSchematicSystem();
}

View File

@@ -181,6 +181,20 @@ public final class Settings {
Blocks.TRAPPED_CHEST
)));
/**
* 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.
* <p>
@@ -231,7 +245,7 @@ public final class Settings {
/**
* If we overshoot a traverse and end up one block beyond the destination, mark it as successful anyway.
* <p>
* This helps with speed at >=20m/s
* This helps with speed exceeding 20m/s
*/
public final Setting<Boolean> overshootTraverse = new Setting<>(true);
@@ -250,6 +264,11 @@ public final class Settings {
*/
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
*/
@@ -740,6 +759,11 @@ public final class Settings {
*/
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
* <p>
@@ -789,6 +813,12 @@ public final class Settings {
*/
public final Setting<Boolean> schematicOrientationZ = new Setting<>(false);
/**
* The fallback used by the build command when no extension is specified. This may be useful if schematics of a
* particular format are used often, and the user does not wish to have to specify the extension with every usage.
*/
public final Setting<String> schematicFallbackExtension = new Setting<>("schematic");
/**
* Distance to scan every tick for updates. Expanding this beyond player reach distance (i.e. setting it to 6 or above)
* is only necessary in very large schematics where rescanning the whole thing is costly.

View File

@@ -81,6 +81,4 @@ public interface ICachedWorld {
* in a new thread by default.
*/
void save();
}

View File

@@ -77,10 +77,20 @@ public interface IWorldScanner {
}
/**
* Repacks 40 chunks around the player.
* Overload of {@link #repack(IPlayerContext, int)} where the value of the {@code range} parameter is {@code 40}.
*
* @param ctx The player context for that player.
* @return The number of chunks queued for repacking.
* @param ctx The player, describing the origin
* @return The amount of chunks successfully queued for repacking
*/
int repack(IPlayerContext ctx);
/**
* Queues the chunks in a square formation around the specified player, using the specified
* range, which represents 1/2 the square's dimensions, where the player is in the center.
*
* @param ctx The player, describing the origin
* @param range The range to repack
* @return The amount of chunks successfully queued for repacking
*/
int repack(IPlayerContext ctx, int range);
}

View File

@@ -38,38 +38,26 @@ public enum RelativeGoal implements IDatatypePost<Goal, BetterBlockPos> {
if (origin == null) {
origin = BetterBlockPos.ORIGIN;
}
final IArgConsumer consumer = ctx.getConsumer();
List<IDatatypePostFunction<Double, Double>> coords = new ArrayList<>();
final IArgConsumer copy = consumer.copy(); // This is a hack and should be fixed in the future probably
for (int i = 0; i < 3; i++) {
if (copy.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) {
coords.add(o -> consumer.getDatatypePost(RelativeCoordinate.INSTANCE, o));
copy.get(); // Consume so we actually decrement the remaining arguments
}
GoalBlock goalBlock = consumer.peekDatatypePostOrNull(RelativeGoalBlock.INSTANCE, origin);
if (goalBlock != null) {
return goalBlock;
}
switch (coords.size()) {
case 0:
return new GoalBlock(origin);
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());
GoalXZ goalXZ = consumer.peekDatatypePostOrNull(RelativeGoalXZ.INSTANCE, origin);
if (goalXZ != null) {
return goalXZ;
}
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

View File

@@ -22,4 +22,8 @@ public abstract class CommandErrorMessageException extends CommandException {
protected CommandErrorMessageException(String reason) {
super(reason);
}
protected CommandErrorMessageException(String reason, Throwable cause) {
super(reason, cause);
}
}

View File

@@ -22,4 +22,8 @@ public abstract class CommandException extends Exception implements ICommandExce
protected CommandException(String reason) {
super(reason);
}
protected CommandException(String reason, Throwable cause) {
super(reason, cause);
}
}

View File

@@ -23,12 +23,21 @@ public abstract class CommandInvalidArgumentException extends CommandErrorMessag
public final ICommandArgument arg;
protected CommandInvalidArgumentException(ICommandArgument arg, String reason) {
super(String.format(
"Error at argument #%s: %s",
arg.getIndex() == -1 ? "<unknown>" : Integer.toString(arg.getIndex() + 1),
reason
));
protected CommandInvalidArgumentException(ICommandArgument arg, String message) {
super(formatMessage(arg, message));
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
);
}
}

View File

@@ -26,7 +26,7 @@ public class CommandInvalidTypeException extends CommandInvalidArgumentException
}
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) {
@@ -34,6 +34,6 @@ public class CommandInvalidTypeException extends CommandInvalidArgumentException
}
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);
}
}

View File

@@ -37,7 +37,7 @@ public class CommandUnhandledException extends RuntimeException implements IComm
@Override
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",
TextFormatting.RED);

View File

@@ -19,22 +19,20 @@ package baritone.api.event.events;
import baritone.api.event.events.type.EventState;
import java.util.function.BiFunction;
public final class TickEvent {
private static int overallTickCount;
private final EventState state;
private final Type type;
private final int count;
private static int overallTickCount;
public TickEvent(EventState state, Type type) {
public TickEvent(EventState state, Type type, int count) {
this.state = state;
this.type = type;
this.count = incrementCount();
}
private static synchronized int incrementCount() {
return overallTickCount++;
this.count = count;
}
public int getCount() {
@@ -49,6 +47,10 @@ public final class TickEvent {
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 {
/**

View File

@@ -23,6 +23,10 @@ public abstract class AbstractSchematic implements ISchematic {
protected int y;
protected int z;
public AbstractSchematic() {
this(0, 0, 0);
}
public AbstractSchematic(int x, int y, int z) {
this.x = x;
this.y = y;

View File

@@ -32,6 +32,10 @@ public class FillSchematic extends AbstractSchematic {
this.bom = bom;
}
public FillSchematic(int x, int y, int z, BlockState state) {
this(x, y, z, new BlockOptionalMeta(state.getBlock()));
}
public BlockOptionalMeta getBom() {
return bom;
}

View File

@@ -0,0 +1,44 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic;
import baritone.api.command.registry.Registry;
import baritone.api.schematic.format.ISchematicFormat;
import java.io.File;
import java.util.Optional;
/**
* @author Brady
* @since 12/23/2019
*/
public interface ISchematicSystem {
/**
* @return The registry of supported schematic formats
*/
Registry<ISchematicFormat> getRegistry();
/**
* Attempts to find an {@link ISchematicFormat} that supports the specified schematic file.
*
* @param file A schematic file
* @return The corresponding format for the file, {@link Optional#empty()} if no candidates were found.
*/
Optional<ISchematicFormat> getByFile(File file);
}

View File

@@ -0,0 +1,60 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic;
import net.minecraft.block.BlockState;
/**
* A static schematic is capable of providing the desired state at a given position without
* additional context. Schematics of this type are expected to have non-varying contents.
*
* @see #getDirect(int, int, int)
*
* @author Brady
* @since 12/24/2019
*/
public interface IStaticSchematic extends ISchematic {
/**
* Gets the {@link BlockState} for a given position in this schematic. It should be guaranteed
* that the return value of this method will not change given that the parameters are the same.
*
* @param x The X block position
* @param y The Y block position
* @param z The Z block position
* @return The desired state at the specified position.
*/
BlockState getDirect(int x, int y, int z);
/**
* Returns an {@link BlockState} array of size {@link #heightY()} which contains all
* desired block states in the specified vertical column. The index of {@link BlockState}s
* in the array are equivalent to their Y position in the schematic.
*
* @param x The X column position
* @param z The Z column position
* @return An {@link BlockState} array
*/
default BlockState[] getColumn(int x, int z) {
BlockState[] column = new BlockState[this.heightY()];
for (int i = 0; i < this.heightY(); i++) {
column[i] = getDirect(x, i, z);
}
return column;
}
}

View File

@@ -0,0 +1,45 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic.format;
import baritone.api.schematic.ISchematic;
import baritone.api.schematic.IStaticSchematic;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* The base of a {@link ISchematic} file format
*
* @author Brady
* @since 12/23/2019
*/
public interface ISchematicFormat {
/**
* @return The parser for creating schematics of this format
*/
IStaticSchematic parse(InputStream input) throws IOException;
/**
* @param file The file to check against
* @return Whether or not the specified file matches this schematic format
*/
boolean isFileType(File file);
}

View File

@@ -21,13 +21,9 @@ import baritone.api.utils.accessor.IItemStack;
import com.google.common.collect.ImmutableSet;
import io.netty.util.concurrent.ThreadPerTaskExecutor;
import net.minecraft.block.*;
import net.minecraft.client.Minecraft;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.resources.*;
import net.minecraft.state.IProperty;
import net.minecraft.state.properties.*;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Unit;
import net.minecraft.util.math.BlockPos;
@@ -37,7 +33,6 @@ import net.minecraft.world.storage.loot.*;
import javax.annotation.Nonnull;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -50,7 +45,6 @@ public final class BlockOptionalMeta {
private final ImmutableSet<Integer> stateHashes;
private final ImmutableSet<Integer> stackHashes;
private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$");
private static final Map<Object, Object> normalizations;
private static LootTableManager manager;
private static Map<Block, List<Item>> drops = new HashMap<>();
@@ -82,142 +76,6 @@ public final class BlockOptionalMeta {
stackHashes = getStackHashes(blockstates);
}
static {
Map<Object, Object> _normalizations = new HashMap<>();
Consumer<Enum> put = instance -> _normalizations.put(instance.getClass(), instance);
put.accept(Direction.NORTH);
put.accept(Direction.Axis.Y);
put.accept(Half.BOTTOM);
put.accept(StairsShape.STRAIGHT);
put.accept(AttachFace.FLOOR);
put.accept(DoubleBlockHalf.UPPER);
put.accept(SlabType.BOTTOM);
put.accept(DoorHingeSide.LEFT);
put.accept(BedPart.HEAD);
put.accept(RailShape.NORTH_SOUTH);
_normalizations.put(BannerBlock.ROTATION, 0);
_normalizations.put(BedBlock.OCCUPIED, false);
_normalizations.put(BrewingStandBlock.HAS_BOTTLE[0], false);
_normalizations.put(BrewingStandBlock.HAS_BOTTLE[1], false);
_normalizations.put(BrewingStandBlock.HAS_BOTTLE[2], false);
_normalizations.put(AbstractButtonBlock.POWERED, false);
// _normalizations.put(BlockCactus.AGE, 0);
// _normalizations.put(BlockCauldron.LEVEL, 0);
// _normalizations.put(BlockChorusFlower.AGE, 0);
_normalizations.put(ChorusPlantBlock.NORTH, false);
_normalizations.put(ChorusPlantBlock.EAST, false);
_normalizations.put(ChorusPlantBlock.SOUTH, false);
_normalizations.put(ChorusPlantBlock.WEST, false);
_normalizations.put(ChorusPlantBlock.UP, false);
_normalizations.put(ChorusPlantBlock.DOWN, false);
// _normalizations.put(BlockCocoa.AGE, 0);
// _normalizations.put(BlockCrops.AGE, 0);
_normalizations.put(SnowyDirtBlock.SNOWY, false);
_normalizations.put(DoorBlock.OPEN, false);
_normalizations.put(DoorBlock.POWERED, false);
// _normalizations.put(BlockFarmland.MOISTURE, 0);
_normalizations.put(FenceBlock.NORTH, false);
_normalizations.put(FenceBlock.EAST, false);
_normalizations.put(FenceBlock.WEST, false);
_normalizations.put(FenceBlock.SOUTH, false);
// _normalizations.put(BlockFenceGate.POWERED, false);
// _normalizations.put(BlockFenceGate.IN_WALL, false);
_normalizations.put(FireBlock.AGE, 0);
_normalizations.put(FireBlock.NORTH, false);
_normalizations.put(FireBlock.EAST, false);
_normalizations.put(FireBlock.SOUTH, false);
_normalizations.put(FireBlock.WEST, false);
_normalizations.put(FireBlock.UP, false);
// _normalizations.put(BlockFrostedIce.AGE, 0);
_normalizations.put(GrassBlock.SNOWY, false);
// _normalizations.put(BlockHopper.ENABLED, true);
// _normalizations.put(BlockLever.POWERED, false);
// _normalizations.put(BlockLiquid.LEVEL, 0);
// _normalizations.put(BlockMycelium.SNOWY, false);
// _normalizations.put(BlockNetherWart.AGE, false);
_normalizations.put(LeavesBlock.DISTANCE, false);
// _normalizations.put(BlockLeaves.DECAYABLE, false);
// _normalizations.put(BlockObserver.POWERED, false);
_normalizations.put(PaneBlock.NORTH, false);
_normalizations.put(PaneBlock.EAST, false);
_normalizations.put(PaneBlock.WEST, false);
_normalizations.put(PaneBlock.SOUTH, false);
// _normalizations.put(BlockPistonBase.EXTENDED, false);
// _normalizations.put(BlockPressurePlate.POWERED, false);
// _normalizations.put(BlockPressurePlateWeighted.POWER, false);
// _normalizations.put(BlockRailDetector.POWERED, false);
// _normalizations.put(BlockRailPowered.POWERED, false);
_normalizations.put(RedstoneWireBlock.NORTH, false);
_normalizations.put(RedstoneWireBlock.EAST, false);
_normalizations.put(RedstoneWireBlock.SOUTH, false);
_normalizations.put(RedstoneWireBlock.WEST, false);
// _normalizations.put(BlockReed.AGE, false);
_normalizations.put(SaplingBlock.STAGE, 0);
_normalizations.put(StandingSignBlock.ROTATION, 0);
_normalizations.put(StemBlock.AGE, 0);
_normalizations.put(TripWireBlock.NORTH, false);
_normalizations.put(TripWireBlock.EAST, false);
_normalizations.put(TripWireBlock.WEST, false);
_normalizations.put(TripWireBlock.SOUTH, false);
_normalizations.put(VineBlock.NORTH, false);
_normalizations.put(VineBlock.EAST, false);
_normalizations.put(VineBlock.SOUTH, false);
_normalizations.put(VineBlock.WEST, false);
_normalizations.put(VineBlock.UP, false);
_normalizations.put(WallBlock.UP, false);
_normalizations.put(WallBlock.NORTH, false);
_normalizations.put(WallBlock.EAST, false);
_normalizations.put(WallBlock.WEST, false);
_normalizations.put(WallBlock.SOUTH, false);
normalizations = Collections.unmodifiableMap(_normalizations);
}
private static <C extends Comparable<C>, P extends IProperty<C>> P castToIProperty(Object value) {
//noinspection unchecked
return (P) value;
}
private static <C extends Comparable<C>, P extends IProperty<C>> C castToIPropertyValue(P iproperty, Object value) {
//noinspection unchecked
return (C) value;
}
public static BlockState normalize(BlockState state) {
BlockState newState = state;
for (IProperty<?> property : state.getProperties()) {
Class<?> valueClass = property.getValueClass();
if (normalizations.containsKey(property)) {
try {
newState = newState.with(
castToIProperty(property),
castToIPropertyValue(property, normalizations.get(property))
);
} catch (IllegalArgumentException ignored) {}
} else if (normalizations.containsKey(state.get(property))) {
try {
newState = newState.with(
castToIProperty(property),
castToIPropertyValue(property, normalizations.get(state.get(property)))
);
} catch (IllegalArgumentException ignored) {}
} else if (normalizations.containsKey(valueClass)) {
try {
newState = newState.with(
castToIProperty(property),
castToIPropertyValue(property, normalizations.get(valueClass))
);
} catch (IllegalArgumentException ignored) {}
}
}
return newState;
}
public static int stateMeta(BlockState state) {
return state.hashCode();
}
private static Set<BlockState> getStates(@Nonnull Block block) {
return new HashSet<>(block.getStateContainer().getValidStates());
}
@@ -296,10 +154,7 @@ public final class BlockOptionalMeta {
return manager;
}
private static List<Item> drops(Block b) {
if (!Minecraft.getInstance().isOnExecutionThread()) {
throw new IllegalStateException();
}
private static synchronized List<Item> drops(Block b) {
return drops.computeIfAbsent(b, block -> {
ResourceLocation lootTableLocation = block.getLootTable();
if (lootTableLocation == LootTables.EMPTY) {

View File

@@ -20,6 +20,7 @@ package baritone.api.utils;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.ClickType;
import baritone.api.BaritoneAPI;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
@@ -56,6 +57,6 @@ public interface IPlayerController {
void setHittingBlock(boolean hittingBlock);
default double getBlockReachDistance() {
return this.getGameType().isCreative() ? 5.0F : 4.5F;
return this.getGameType().isCreative() ? 5.0F : BaritoneAPI.getSettings().blockReachDistance.value;
}
}

View File

@@ -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.LocalCapture;
import java.util.function.BiFunction;
/**
* @author Brady
* @since 7/31/2018
@@ -84,13 +86,15 @@ public class MixinMinecraft {
)
)
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.OUT;
ibaritone.getGameEventHandler().onTick(new TickEvent(EventState.PRE, type));
baritone.getGameEventHandler().onTick(tickProvider.apply(EventState.PRE, type));
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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"
);
}
}

View File

@@ -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);
}
}

View File

@@ -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"
);
}
};
}
}

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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() {
}
}

View File

@@ -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) {

View File

@@ -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();
}
}

View File

@@ -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];
}
}

View 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();
}
}

View File

@@ -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];
}
}

View File

@@ -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()));
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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

View File

@@ -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));
}

View 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);
}
}