Schematic Format API support
This commit is contained in:
parent
77bdf6e444
commit
eee705b371
@ -20,6 +20,7 @@ package baritone.api;
|
||||
import baritone.api.cache.IWorldScanner;
|
||||
import baritone.api.command.ICommand;
|
||||
import baritone.api.command.ICommandSystem;
|
||||
import baritone.api.schematic.ISchematicSystem;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
|
||||
import java.util.List;
|
||||
@ -82,4 +83,9 @@ public interface IBaritoneProvider {
|
||||
* @return The {@link ICommandSystem} instance.
|
||||
*/
|
||||
ICommandSystem getCommandSystem();
|
||||
|
||||
/**
|
||||
* @return The {@link ISchematicSystem} instance.
|
||||
*/
|
||||
ISchematicSystem getSchematicSystem();
|
||||
}
|
||||
|
44
src/api/java/baritone/api/schematic/ISchematicSystem.java
Normal file
44
src/api/java/baritone/api/schematic/ISchematicSystem.java
Normal 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);
|
||||
}
|
60
src/api/java/baritone/api/schematic/IStaticSchematic.java
Normal file
60
src/api/java/baritone/api/schematic/IStaticSchematic.java
Normal 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.state.IBlockState;
|
||||
|
||||
/**
|
||||
* 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 IBlockState} 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.
|
||||
*/
|
||||
IBlockState getDirect(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Returns an {@link IBlockState} array of size {@link #heightY()} which contains all
|
||||
* desired block states in the specified vertical column. The index of {@link IBlockState}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 IBlockState} array
|
||||
*/
|
||||
default IBlockState[] getColumn(int x, int z) {
|
||||
IBlockState[] column = new IBlockState[this.heightY()];
|
||||
for (int i = 0; i < this.heightY(); i++) {
|
||||
column[i] = getDirect(x, i, z);
|
||||
}
|
||||
return column;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.parse.ISchematicParser;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
ISchematicParser getParser();
|
||||
|
||||
/**
|
||||
* @param file The file to check against
|
||||
* @return Whether or not the specified file matches this schematic format
|
||||
*/
|
||||
boolean isFileType(File file);
|
||||
}
|
@ -15,9 +15,9 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.utils.schematic.parse;
|
||||
package baritone.api.schematic.parse;
|
||||
|
||||
import baritone.utils.schematic.StaticSchematic;
|
||||
import baritone.api.schematic.IStaticSchematic;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -28,5 +28,5 @@ import java.io.InputStream;
|
||||
*/
|
||||
public interface ISchematicParser {
|
||||
|
||||
StaticSchematic parse(InputStream input) throws IOException;
|
||||
IStaticSchematic parse(InputStream input) throws IOException;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ import baritone.api.process.PathingCommand;
|
||||
import baritone.api.process.PathingCommandType;
|
||||
import baritone.api.schematic.FillSchematic;
|
||||
import baritone.api.schematic.ISchematic;
|
||||
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;
|
||||
@ -39,8 +41,7 @@ import baritone.utils.BaritoneProcessHelper;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.PathingCommandContext;
|
||||
import baritone.utils.schematic.MapArtSchematic;
|
||||
import baritone.utils.schematic.StaticSchematic;
|
||||
import baritone.utils.schematic.format.SchematicFormat;
|
||||
import baritone.utils.schematic.SchematicSystem;
|
||||
import baritone.utils.schematic.schematica.SchematicaHelper;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import net.minecraft.block.BlockAir;
|
||||
@ -116,7 +117,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
||||
|
||||
@Override
|
||||
public boolean build(String name, File schematic, Vec3i origin) {
|
||||
Optional<SchematicFormat> format = SchematicFormat.getByFile(schematic);
|
||||
Optional<ISchematicFormat> format = SchematicSystem.INSTANCE.getByFile(schematic);
|
||||
if (!format.isPresent()) {
|
||||
return false;
|
||||
}
|
||||
@ -130,7 +131,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
||||
}
|
||||
|
||||
if (Baritone.settings().mapArtMode.value) {
|
||||
parsed = new MapArtSchematic((StaticSchematic) parsed);
|
||||
parsed = new MapArtSchematic((IStaticSchematic) parsed);
|
||||
}
|
||||
|
||||
build(name, parsed, origin);
|
||||
|
@ -17,20 +17,54 @@
|
||||
|
||||
package baritone.utils.schematic;
|
||||
|
||||
import baritone.api.schematic.IStaticSchematic;
|
||||
import baritone.api.schematic.MaskSchematic;
|
||||
import net.minecraft.block.BlockAir;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class MapArtSchematic extends MaskSchematic {
|
||||
|
||||
private final int[][] heightMap;
|
||||
|
||||
public MapArtSchematic(StaticSchematic schematic) {
|
||||
public MapArtSchematic(IStaticSchematic schematic) {
|
||||
super(schematic);
|
||||
this.heightMap = schematic.getHeightMap();
|
||||
this.heightMap = generateHeightMap(schematic);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {
|
||||
return y >= heightMap[x][z];
|
||||
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++) {
|
||||
IBlockState[] column = schematic.getColumn(x, z);
|
||||
|
||||
OptionalInt lowestBlockY = lastIndexMatching(column, state -> !(state.getBlock() instanceof BlockAir));
|
||||
if (lowestBlockY.isPresent()) {
|
||||
heightMap[x][z] = lowestBlockY.getAsInt();
|
||||
} else {
|
||||
System.out.println("Column " + x + "," + z + " has no blocks, but it's apparently map art? wtf");
|
||||
System.out.println("Letting it be whatever");
|
||||
heightMap[x][z] = 256;
|
||||
}
|
||||
}
|
||||
}
|
||||
return heightMap;
|
||||
}
|
||||
|
||||
private static <T> OptionalInt lastIndexMatching(T[] arr, Predicate<? super T> predicate) {
|
||||
for (int y = arr.length - 1; y >= 0; y--) {
|
||||
if (predicate.test(arr[y])) {
|
||||
return OptionalInt.of(y);
|
||||
}
|
||||
}
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
}
|
||||
|
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();
|
||||
}
|
||||
}
|
@ -18,71 +18,33 @@
|
||||
package baritone.utils.schematic;
|
||||
|
||||
import baritone.api.schematic.AbstractSchematic;
|
||||
import net.minecraft.block.BlockAir;
|
||||
import baritone.api.schematic.IStaticSchematic;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link IStaticSchematic}
|
||||
*
|
||||
* @author Brady
|
||||
* @since 12/23/2019
|
||||
*/
|
||||
public abstract class StaticSchematic extends AbstractSchematic {
|
||||
public class StaticSchematic extends AbstractSchematic implements IStaticSchematic {
|
||||
|
||||
/**
|
||||
* Block states for this schematic stored in [x, z, y] indexing order
|
||||
*/
|
||||
protected IBlockState[][][] states;
|
||||
|
||||
/**
|
||||
* The maximum height of a given block in this schematic, indexed as [x, z].
|
||||
* This is lazily initialized by {@link #getHeightMap()}.
|
||||
*/
|
||||
protected int[][] heightMap;
|
||||
|
||||
public StaticSchematic() {
|
||||
super();
|
||||
}
|
||||
|
||||
public StaticSchematic(int x, int y, int z) {
|
||||
super(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
|
||||
return this.states[x][z][y];
|
||||
}
|
||||
|
||||
public final int[][] getHeightMap() {
|
||||
if (this.heightMap == null) {
|
||||
this.heightMap = new int[this.x][this.z];
|
||||
|
||||
for (int x = 0; x < this.x; x++) {
|
||||
for (int z = 0; z < this.z; z++) {
|
||||
IBlockState[] column = states[x][z];
|
||||
|
||||
OptionalInt lowestBlockY = lastIndexMatching(column, state -> !(state.getBlock() instanceof BlockAir));
|
||||
if (lowestBlockY.isPresent()) {
|
||||
this.heightMap[x][z] = lowestBlockY.getAsInt();
|
||||
} else {
|
||||
System.out.println("Column " + x + "," + z + " has no blocks, but it's apparently map art? wtf");
|
||||
System.out.println("Letting it be whatever");
|
||||
this.heightMap[x][z] = 256;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.heightMap;
|
||||
@Override
|
||||
public IBlockState getDirect(int x, int y, int z) {
|
||||
return this.states[x][z][y];
|
||||
}
|
||||
|
||||
private static <T> OptionalInt lastIndexMatching(T[] arr, Predicate<? super T> predicate) {
|
||||
for (int y = arr.length - 1; y >= 0; y--) {
|
||||
if (predicate.test(arr[y])) {
|
||||
return OptionalInt.of(y);
|
||||
}
|
||||
}
|
||||
return OptionalInt.empty();
|
||||
@Override
|
||||
public IBlockState[] getColumn(int x, int z) {
|
||||
return this.states[x][z];
|
||||
}
|
||||
}
|
||||
|
@ -17,20 +17,21 @@
|
||||
|
||||
package baritone.utils.schematic.format;
|
||||
|
||||
import baritone.utils.schematic.parse.ISchematicParser;
|
||||
import baritone.api.schematic.format.ISchematicFormat;
|
||||
import baritone.api.schematic.parse.ISchematicParser;
|
||||
import baritone.utils.schematic.parse.MCEditParser;
|
||||
import baritone.utils.schematic.parse.SpongeParser;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Default implementations of {@link ISchematicFormat}
|
||||
*
|
||||
* @author Brady
|
||||
* @since 12/13/2019
|
||||
*/
|
||||
public enum SchematicFormat {
|
||||
public enum DefaultSchematicFormats implements ISchematicFormat {
|
||||
|
||||
/**
|
||||
* The MCEdit schematic specification. Commonly denoted by the ".schematic" file extension.
|
||||
@ -47,24 +48,18 @@ public enum SchematicFormat {
|
||||
private final String extension;
|
||||
private final ISchematicParser parser;
|
||||
|
||||
SchematicFormat(String extension, ISchematicParser parser) {
|
||||
DefaultSchematicFormats(String extension, ISchematicParser parser) {
|
||||
this.extension = extension;
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ISchematicParser getParser() {
|
||||
return this.parser;
|
||||
}
|
||||
|
||||
public static Optional<SchematicFormat> getByFile(File schematic) {
|
||||
// TODO: Better identification
|
||||
// Maybe peek file contents and make a safe determination?
|
||||
return getByExtension(FilenameUtils.getExtension(schematic.getAbsolutePath()));
|
||||
}
|
||||
|
||||
public static Optional<SchematicFormat> getByExtension(String extension) {
|
||||
return extension == null || extension.isEmpty()
|
||||
? Optional.empty()
|
||||
: Stream.of(values()).filter(format -> format.extension.equalsIgnoreCase(extension)).findFirst();
|
||||
@Override
|
||||
public boolean isFileType(File file) {
|
||||
return this.extension.equalsIgnoreCase(FilenameUtils.getExtension(file.getAbsolutePath()));
|
||||
}
|
||||
}
|
@ -17,8 +17,9 @@
|
||||
|
||||
package baritone.utils.schematic.parse;
|
||||
|
||||
import baritone.api.schematic.parse.ISchematicParser;
|
||||
import baritone.utils.schematic.StaticSchematic;
|
||||
import baritone.utils.schematic.format.SchematicFormat;
|
||||
import baritone.utils.schematic.format.DefaultSchematicFormats;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
@ -28,7 +29,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* An implementation of {@link ISchematicParser} for {@link SchematicFormat#MCEDIT}
|
||||
* An implementation of {@link ISchematicParser} for {@link DefaultSchematicFormats#MCEDIT}
|
||||
*
|
||||
* @author Brady
|
||||
* @since 12/16/2019
|
||||
|
@ -17,8 +17,9 @@
|
||||
|
||||
package baritone.utils.schematic.parse;
|
||||
|
||||
import baritone.api.schematic.parse.ISchematicParser;
|
||||
import baritone.utils.schematic.StaticSchematic;
|
||||
import baritone.utils.schematic.format.SchematicFormat;
|
||||
import baritone.utils.schematic.format.DefaultSchematicFormats;
|
||||
import baritone.utils.type.VarInt;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||
import net.minecraft.block.Block;
|
||||
@ -37,7 +38,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* An implementation of {@link ISchematicParser} for {@link SchematicFormat#SPONGE}
|
||||
* An implementation of {@link ISchematicParser} for {@link DefaultSchematicFormats#SPONGE}
|
||||
*
|
||||
* @author Brady
|
||||
* @since 12/16/2019
|
||||
|
Loading…
Reference in New Issue
Block a user