Merge pull request #1 from rycbar0/LitematicaCommand
Adding a Litematica command to build loaded schematics.
This commit is contained in:
2
scripts/proguard.pro
vendored
2
scripts/proguard.pro
vendored
@@ -42,8 +42,10 @@
|
|||||||
|
|
||||||
#try to keep usage of schematica in separate classes
|
#try to keep usage of schematica in separate classes
|
||||||
-keep class baritone.utils.schematic.schematica.**
|
-keep class baritone.utils.schematic.schematica.**
|
||||||
|
-keep class baritone.utils.schematic.litematica.**
|
||||||
#proguard doesnt like it when it cant find our fake schematica classes
|
#proguard doesnt like it when it cant find our fake schematica classes
|
||||||
-dontwarn baritone.utils.schematic.schematica.**
|
-dontwarn baritone.utils.schematic.schematica.**
|
||||||
|
-dontwarn baritone.utils.schematic.litematica.**
|
||||||
|
|
||||||
# copy all necessary libraries into tempLibraries to build
|
# copy all necessary libraries into tempLibraries to build
|
||||||
|
|
||||||
|
@@ -58,6 +58,8 @@ public interface IBuilderProcess extends IBaritoneProcess {
|
|||||||
|
|
||||||
void buildOpenSchematic();
|
void buildOpenSchematic();
|
||||||
|
|
||||||
|
void buildOpenLitematic(int i);
|
||||||
|
|
||||||
void pause();
|
void pause();
|
||||||
|
|
||||||
boolean isPaused();
|
boolean isPaused();
|
||||||
|
@@ -43,6 +43,7 @@ public final class DefaultCommands {
|
|||||||
new RepackCommand(baritone),
|
new RepackCommand(baritone),
|
||||||
new BuildCommand(baritone),
|
new BuildCommand(baritone),
|
||||||
new SchematicaCommand(baritone),
|
new SchematicaCommand(baritone),
|
||||||
|
new LitematicaCommand(baritone),
|
||||||
new ComeCommand(baritone),
|
new ComeCommand(baritone),
|
||||||
new AxisCommand(baritone),
|
new AxisCommand(baritone),
|
||||||
new ForceCancelCommand(baritone),
|
new ForceCancelCommand(baritone),
|
||||||
|
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* 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.argument.IArgConsumer;
|
||||||
|
import baritone.api.command.exception.CommandException;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class LitematicaCommand extends Command {
|
||||||
|
|
||||||
|
public LitematicaCommand(IBaritone baritone) {
|
||||||
|
super(baritone, "litematica");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(String label, IArgConsumer args) throws CommandException {
|
||||||
|
int schematic = 0;
|
||||||
|
if(args.hasAny()) {
|
||||||
|
args.requireMax(1);
|
||||||
|
if (args.is(Integer.class)) {
|
||||||
|
schematic = args.getAs(Integer.class)-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
baritone.getBuilderProcess().buildOpenLitematic(schematic);
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
logDirect("Pleas provide a valid index.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<String> tabComplete(String label, IArgConsumer args) {
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getShortDesc() {
|
||||||
|
return "Builds the loaded schematic";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getLongDesc() {
|
||||||
|
return Arrays.asList(
|
||||||
|
"Build a schematic currently open in Litematica.",
|
||||||
|
"",
|
||||||
|
"Usage:",
|
||||||
|
"> litematica",
|
||||||
|
"> litematica <#>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -26,9 +26,9 @@ import baritone.api.process.IBuilderProcess;
|
|||||||
import baritone.api.process.PathingCommand;
|
import baritone.api.process.PathingCommand;
|
||||||
import baritone.api.process.PathingCommandType;
|
import baritone.api.process.PathingCommandType;
|
||||||
import baritone.api.schematic.FillSchematic;
|
import baritone.api.schematic.FillSchematic;
|
||||||
import baritone.api.schematic.SubstituteSchematic;
|
|
||||||
import baritone.api.schematic.ISchematic;
|
import baritone.api.schematic.ISchematic;
|
||||||
import baritone.api.schematic.IStaticSchematic;
|
import baritone.api.schematic.IStaticSchematic;
|
||||||
|
import baritone.api.schematic.SubstituteSchematic;
|
||||||
import baritone.api.schematic.format.ISchematicFormat;
|
import baritone.api.schematic.format.ISchematicFormat;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
import baritone.api.utils.RayTraceUtils;
|
import baritone.api.utils.RayTraceUtils;
|
||||||
@@ -42,8 +42,10 @@ import baritone.utils.BaritoneProcessHelper;
|
|||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.PathingCommandContext;
|
import baritone.utils.PathingCommandContext;
|
||||||
import baritone.utils.schematic.MapArtSchematic;
|
import baritone.utils.schematic.MapArtSchematic;
|
||||||
import baritone.utils.schematic.SelectionSchematic;
|
|
||||||
import baritone.utils.schematic.SchematicSystem;
|
import baritone.utils.schematic.SchematicSystem;
|
||||||
|
import baritone.utils.schematic.SelectionSchematic;
|
||||||
|
import baritone.utils.schematic.format.defaults.LitematicaSchematic;
|
||||||
|
import baritone.utils.schematic.litematica.LitematicaHelper;
|
||||||
import baritone.utils.schematic.schematica.SchematicaHelper;
|
import baritone.utils.schematic.schematica.SchematicaHelper;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
@@ -54,12 +56,15 @@ import net.minecraft.block.state.IBlockState;
|
|||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.item.ItemBlock;
|
import net.minecraft.item.ItemBlock;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompressedStreamTools;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.Tuple;
|
import net.minecraft.util.Tuple;
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -176,6 +181,33 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the with index 'i' given schematic placement.
|
||||||
|
*
|
||||||
|
* @param i index reference to the schematic placement list.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void buildOpenLitematic(int i) {
|
||||||
|
if (LitematicaHelper.isLitematicaPresent()) {
|
||||||
|
//if java.lang.NoSuchMethodError is thrown see comment in SchematicPlacementManager
|
||||||
|
if (LitematicaHelper.hasLoadedSchematic()) {
|
||||||
|
String name = LitematicaHelper.getName(i);
|
||||||
|
try {
|
||||||
|
LitematicaSchematic schematic1 = new LitematicaSchematic(CompressedStreamTools.readCompressed(Files.newInputStream(LitematicaHelper.getSchematicFile(i).toPath())), false);
|
||||||
|
Vec3i correctedOrigin = LitematicaHelper.getCorrectedOrigin(schematic1, i);
|
||||||
|
LitematicaSchematic schematic2 = LitematicaHelper.blackMagicFuckery(schematic1, i);
|
||||||
|
build(name, schematic2, correctedOrigin);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logDirect("Schematic File could not be loaded.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logDirect("No schematic currently loaded");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logDirect("Litematica is not present");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void clearArea(BlockPos corner1, BlockPos corner2) {
|
public void clearArea(BlockPos corner1, BlockPos corner2) {
|
||||||
BlockPos origin = new BlockPos(Math.min(corner1.getX(), corner2.getX()), Math.min(corner1.getY(), corner2.getY()), Math.min(corner1.getZ(), corner2.getZ()));
|
BlockPos origin = new BlockPos(Math.min(corner1.getX(), corner2.getX()), Math.min(corner1.getY(), corner2.getY()), Math.min(corner1.getZ(), corner2.getZ()));
|
||||||
int widthX = Math.abs(corner1.getX() - corner2.getX()) + 1;
|
int widthX = Math.abs(corner1.getX() - corner2.getX()) + 1;
|
||||||
|
@@ -78,7 +78,7 @@ public enum DefaultSchematicFormats implements ISchematicFormat {
|
|||||||
int version = nbt.getInteger("Version");
|
int version = nbt.getInteger("Version");
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case 4: //1.12
|
case 4: //1.12
|
||||||
return new LitematicaSchematic(nbt);
|
return new LitematicaSchematic(nbt, false);
|
||||||
case 5: //1.13-1.17
|
case 5: //1.13-1.17
|
||||||
case 6: //1.18+
|
case 6: //1.18+
|
||||||
throw new UnsupportedOperationException("This litematic Verion is to new.");
|
throw new UnsupportedOperationException("This litematic Verion is to new.");
|
||||||
|
@@ -25,6 +25,7 @@ import net.minecraft.block.state.IBlockState;
|
|||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.Vec3i;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -37,40 +38,27 @@ import java.util.Optional;
|
|||||||
* @since 22.09.2022
|
* @since 22.09.2022
|
||||||
*/
|
*/
|
||||||
public final class LitematicaSchematic extends StaticSchematic {
|
public final class LitematicaSchematic extends StaticSchematic {
|
||||||
private final int minX;
|
private final Vec3i offsetMinCorner;
|
||||||
private final int minY;
|
private final NBTTagCompound nbt;
|
||||||
private final int minZ;
|
|
||||||
|
|
||||||
public LitematicaSchematic(NBTTagCompound nbt) {
|
/**
|
||||||
int x = 0;
|
* @param nbtTagCompound a decompressed file stream aka nbt data.
|
||||||
int y = 0;
|
* @param rotated if the schematic is rotated by 90° aka x and z size are switched.
|
||||||
int z = 0;
|
*/
|
||||||
for (String subReg : getRegions(nbt)) {
|
public LitematicaSchematic(NBTTagCompound nbtTagCompound, boolean rotated) {
|
||||||
x = Math.min(x, getMinimumCoord(nbt, subReg, "x"));
|
this.nbt = nbtTagCompound;
|
||||||
y = Math.min(y, getMinimumCoord(nbt, subReg, "y"));
|
this.offsetMinCorner = new Vec3i(getMinOfSchematic("x"), getMinOfSchematic("y"), getMinOfSchematic("z"));
|
||||||
z = Math.min(z, getMinimumCoord(nbt, subReg, "z"));
|
|
||||||
}
|
|
||||||
this.minX = x;
|
|
||||||
this.minY = y;
|
|
||||||
this.minZ = z;
|
|
||||||
|
|
||||||
this.x = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("x"));
|
|
||||||
this.y = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("y"));
|
this.y = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("y"));
|
||||||
|
|
||||||
|
if (rotated) {
|
||||||
|
this.x = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("z"));
|
||||||
|
this.z = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("x"));
|
||||||
|
} else {
|
||||||
|
this.x = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("x"));
|
||||||
this.z = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("z"));
|
this.z = Math.abs(nbt.getCompoundTag("Metadata").getCompoundTag("EnclosingSize").getInteger("z"));
|
||||||
this.states = new IBlockState[this.x][this.z][this.y];
|
|
||||||
|
|
||||||
for (String subReg : getRegions(nbt)) {
|
|
||||||
NBTTagList usedBlockTypes = nbt.getCompoundTag("Regions").getCompoundTag(subReg).getTagList("BlockStatePalette", 10);
|
|
||||||
IBlockState[] blockList = getBlockList(usedBlockTypes);
|
|
||||||
|
|
||||||
int bitsPerBlock = getBitsPerBlock(usedBlockTypes.tagCount());
|
|
||||||
long regionVolume = getVolume(nbt, subReg);
|
|
||||||
long[] blockStateArray = getBlockStates(nbt, subReg);
|
|
||||||
|
|
||||||
LitematicaBitArray bitArray = new LitematicaBitArray(bitsPerBlock, regionVolume, blockStateArray);
|
|
||||||
|
|
||||||
writeSubregionIntoSchematic(nbt, subReg, blockList, bitArray);
|
|
||||||
}
|
}
|
||||||
|
this.states = new IBlockState[this.x][this.z][this.y];
|
||||||
|
fillInSchematic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,12 +69,12 @@ public final class LitematicaSchematic extends StaticSchematic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets both ends from schematic box for a given axis and returns the lower one.
|
* Gets both ends from a region box for a given axis and returns the lower one.
|
||||||
*
|
*
|
||||||
* @param s axis that should be read.
|
* @param s axis that should be read.
|
||||||
* @return the lower coord of the requested axis.
|
* @return the lower coord of the requested axis.
|
||||||
*/
|
*/
|
||||||
private static int getMinimumCoord(NBTTagCompound nbt, String subReg, String s) {
|
private static int getMinOfSubregion(NBTTagCompound nbt, String subReg, String s) {
|
||||||
int a = nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Position").getInteger(s);
|
int a = nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Position").getInteger(s);
|
||||||
int b = nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Size").getInteger(s);
|
int b = nbt.getCompoundTag("Regions").getCompoundTag(subReg).getCompoundTag("Size").getInteger(s);
|
||||||
if (b < 0) {
|
if (b < 0) {
|
||||||
@@ -186,22 +174,49 @@ public final class LitematicaSchematic extends StaticSchematic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param blockList list with the different block types used in the schematic
|
* @param s axis.
|
||||||
* @param bitArray bit array that holds the placement pattern
|
* @return the lowest coordinate of that axis of the schematic.
|
||||||
|
*/
|
||||||
|
private int getMinOfSchematic(String s) {
|
||||||
|
int n = Integer.MAX_VALUE;
|
||||||
|
for (String subReg : getRegions(nbt)) {
|
||||||
|
n = Math.min(n, getMinOfSubregion(nbt, subReg, s));
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the file data.
|
||||||
|
*/
|
||||||
|
private void fillInSchematic() {
|
||||||
|
for (String subReg : getRegions(nbt)) {
|
||||||
|
NBTTagList usedBlockTypes = nbt.getCompoundTag("Regions").getCompoundTag(subReg).getTagList("BlockStatePalette", 10);
|
||||||
|
IBlockState[] blockList = getBlockList(usedBlockTypes);
|
||||||
|
|
||||||
|
int bitsPerBlock = getBitsPerBlock(usedBlockTypes.tagCount());
|
||||||
|
long regionVolume = getVolume(nbt, subReg);
|
||||||
|
long[] blockStateArray = getBlockStates(nbt, subReg);
|
||||||
|
|
||||||
|
LitematicaBitArray bitArray = new LitematicaBitArray(bitsPerBlock, regionVolume, blockStateArray);
|
||||||
|
|
||||||
|
writeSubregionIntoSchematic(nbt, subReg, blockList, bitArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the file data in to the IBlockstate array.
|
||||||
|
*
|
||||||
|
* @param blockList list with the different block types used in the schematic.
|
||||||
|
* @param bitArray bit array that holds the placement pattern.
|
||||||
*/
|
*/
|
||||||
//x,y,z are the releative positons to the minimum corner of the enclosing box
|
|
||||||
//minX,minY,minZ are correction terms if the schematic origin isn't the minimum corner
|
|
||||||
//posX,posY,posZ are the subregions offset relative to the minimum corner
|
|
||||||
private void writeSubregionIntoSchematic(NBTTagCompound nbt, String subReg, IBlockState[] blockList, LitematicaBitArray bitArray) {
|
private void writeSubregionIntoSchematic(NBTTagCompound nbt, String subReg, IBlockState[] blockList, LitematicaBitArray bitArray) {
|
||||||
int posX = getMinimumCoord(nbt, subReg, "x");
|
Vec3i offsetSubregion = new Vec3i(getMinOfSubregion(nbt, subReg, "x"), getMinOfSubregion(nbt, subReg, "y"), getMinOfSubregion(nbt, subReg, "z"));
|
||||||
int posY = getMinimumCoord(nbt, subReg, "y");
|
|
||||||
int posZ = getMinimumCoord(nbt, subReg, "z");
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int y = 0; y < this.y; y++) {
|
for (int y = 0; y < this.y; y++) {
|
||||||
for (int z = 0; z < this.z; z++) {
|
for (int z = 0; z < this.z; z++) {
|
||||||
for (int x = 0; x < this.x; x++) {
|
for (int x = 0; x < this.x; x++) {
|
||||||
if (inSubregion(nbt, subReg, x, y, z)) {
|
if (inSubregion(nbt, subReg, x, y, z)) {
|
||||||
this.states[x - (minX - posX)][z - (minZ - posZ)][y - (minY - posY)] = blockList[bitArray.getAt(index)];
|
this.states[x - (offsetMinCorner.getX() - offsetSubregion.getX())][z - (offsetMinCorner.getZ() - offsetSubregion.getZ())][y - (offsetMinCorner.getY() - offsetSubregion.getY())] = blockList[bitArray.getAt(index)];
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,6 +224,52 @@ public final class LitematicaSchematic extends StaticSchematic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return offset from the schematic origin to the minimum Corner as a Vec3i.
|
||||||
|
*/
|
||||||
|
public Vec3i getOffsetMinCorner() {
|
||||||
|
return offsetMinCorner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return x size of the schematic.
|
||||||
|
*/
|
||||||
|
public int getX() {
|
||||||
|
return this.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return y size of the schematic.
|
||||||
|
*/
|
||||||
|
public int getY() {
|
||||||
|
return this.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return z size of the schematic.
|
||||||
|
*/
|
||||||
|
public int getZ() {
|
||||||
|
return this.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param x position relative to the minimum corner of the schematic.
|
||||||
|
* @param y position relative to the minimum corner of the schematic.
|
||||||
|
* @param z position relative to the minimum corner of the schematic.
|
||||||
|
* @param blockState new blockstate of the block at this position.
|
||||||
|
*/
|
||||||
|
public void setDirect(int x, int y, int z, IBlockState blockState) {
|
||||||
|
this.states[x][z][y] = blockState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param rotated if the schematic is rotated by 90°.
|
||||||
|
* @return a copy of the schematic.
|
||||||
|
*/
|
||||||
|
public LitematicaSchematic getCopy(boolean rotated) {
|
||||||
|
return new LitematicaSchematic(nbt, rotated);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author maruohon
|
* @author maruohon
|
||||||
* Class from the Litematica mod by maruohon
|
* Class from the Litematica mod by maruohon
|
||||||
|
@@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* 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.litematica;
|
||||||
|
|
||||||
|
import baritone.utils.schematic.format.defaults.LitematicaSchematic;
|
||||||
|
import fi.dy.masa.litematica.Litematica;
|
||||||
|
import fi.dy.masa.litematica.data.DataManager;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.util.Mirror;
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
|
import net.minecraft.util.math.Vec3i;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class that provides access or processes data related to Litmatica schematics.
|
||||||
|
*
|
||||||
|
* @author rycbar
|
||||||
|
* @since 28.09.2022
|
||||||
|
*/
|
||||||
|
public final class LitematicaHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return if Litmatica is installed.
|
||||||
|
*/
|
||||||
|
public static boolean isLitematicaPresent() {
|
||||||
|
try {
|
||||||
|
Class.forName(Litematica.class.getName());
|
||||||
|
return true;
|
||||||
|
} catch (ClassNotFoundException | NoClassDefFoundError ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return if there are loaded schematics.
|
||||||
|
*/
|
||||||
|
public static boolean hasLoadedSchematic() {
|
||||||
|
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i index of the Schematic in the schematic placement list.
|
||||||
|
* @return the name of the requested schematic.
|
||||||
|
*/
|
||||||
|
public static String getName(int i) {
|
||||||
|
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i).getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i index of the Schematic in the schematic placement list.
|
||||||
|
* @return the world coordinates of the schematic origin. This can but does not have to be the minimum corner.
|
||||||
|
*/
|
||||||
|
public static Vec3i getOrigin(int i) {
|
||||||
|
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i).getOrigin();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i index of the Schematic in the schematic placement list.
|
||||||
|
* @return Filepath of the schematic file.
|
||||||
|
*/
|
||||||
|
public static File getSchematicFile(int i) {
|
||||||
|
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i).getSchematicFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i index of the Schematic in the schematic placement list.
|
||||||
|
* @return rotation of the schematic placement.
|
||||||
|
*/
|
||||||
|
public static Rotation getRotation(int i) {
|
||||||
|
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i).getRotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i index of the Schematic in the schematic placement list.
|
||||||
|
* @return the mirroring of the schematic placement.
|
||||||
|
*/
|
||||||
|
public static Mirror getMirror(int i) {
|
||||||
|
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i).getMirror();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param schematic original schematic.
|
||||||
|
* @param i index of the Schematic in the schematic placement list.
|
||||||
|
* @return the minimum corner coordinates of the schematic, after the original schematic got rotated and mirrored.
|
||||||
|
*/
|
||||||
|
public static Vec3i getCorrectedOrigin(LitematicaSchematic schematic, int i) {
|
||||||
|
int x = LitematicaHelper.getOrigin(i).getX();
|
||||||
|
int y = LitematicaHelper.getOrigin(i).getY();
|
||||||
|
int z = LitematicaHelper.getOrigin(i).getZ();
|
||||||
|
int mx = schematic.getOffsetMinCorner().getX();
|
||||||
|
int my = schematic.getOffsetMinCorner().getY();
|
||||||
|
int mz = schematic.getOffsetMinCorner().getZ();
|
||||||
|
int sx = (schematic.getX() - 1) * -1;
|
||||||
|
int sz = (schematic.getZ() - 1) * -1;
|
||||||
|
|
||||||
|
Vec3i correctedOrigin;
|
||||||
|
Mirror mirror = LitematicaHelper.getMirror(i);
|
||||||
|
Rotation rotation = LitematicaHelper.getRotation(i);
|
||||||
|
|
||||||
|
//todo there has to be a better way to do this but i cant finde it atm
|
||||||
|
switch (mirror) {
|
||||||
|
case FRONT_BACK:
|
||||||
|
case LEFT_RIGHT:
|
||||||
|
switch ((mirror.ordinal() * 2 + rotation.ordinal()) % 4) {
|
||||||
|
case 1:
|
||||||
|
correctedOrigin = new Vec3i(x + (sz - mz), y + my, z + (sx - mx));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
correctedOrigin = new Vec3i(x + mx, y + my, z + (sz - mz));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
correctedOrigin = new Vec3i(x + mz, y + my, z + mx);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
correctedOrigin = new Vec3i(x + (sx - mx), y + my, z + mz);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
switch (rotation) {
|
||||||
|
case CLOCKWISE_90:
|
||||||
|
correctedOrigin = new Vec3i(x + (sz - mz), y + my, z + mx);
|
||||||
|
break;
|
||||||
|
case CLOCKWISE_180:
|
||||||
|
correctedOrigin = new Vec3i(x + (sx - mx), y + my, z + (sz - mz));
|
||||||
|
break;
|
||||||
|
case COUNTERCLOCKWISE_90:
|
||||||
|
correctedOrigin = new Vec3i(x + mz, y + my, z + (sx - mx));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
correctedOrigin = new Vec3i(x + mx, y + my, z + mz);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return correctedOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param in the xyz offsets of the block relative to the schematic minimum corner.
|
||||||
|
* @param sizeX size of the schematic in the x-axis direction.
|
||||||
|
* @param sizeZ size of the schematic in the z-axis direction.
|
||||||
|
* @param mirror the mirroring of the schematic placement.
|
||||||
|
* @return the corresponding xyz coordinates after mirroring them according to the given mirroring.
|
||||||
|
*/
|
||||||
|
public static Vec3i doMirroring(Vec3i in, int sizeX, int sizeZ, Mirror mirror) {
|
||||||
|
int xOut = in.getX();
|
||||||
|
int zOut = in.getZ();
|
||||||
|
if (mirror == Mirror.LEFT_RIGHT) {
|
||||||
|
zOut = sizeZ - in.getZ();
|
||||||
|
} else if (mirror == Mirror.FRONT_BACK) {
|
||||||
|
xOut = sizeX - in.getX();
|
||||||
|
}
|
||||||
|
return new Vec3i(xOut, in.getY(), zOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param in the xyz offsets of the block relative to the schematic minimum corner.
|
||||||
|
* @param sizeX size of the schematic in the x-axis direction.
|
||||||
|
* @param sizeZ size of the schematic in the z-axis direction.
|
||||||
|
* @return the corresponding xyz coordinates after rotation them 90° clockwise.
|
||||||
|
*/
|
||||||
|
public static Vec3i rotate(Vec3i in, int sizeX, int sizeZ) {
|
||||||
|
return new Vec3i(sizeX - (sizeX - sizeZ) - in.getZ(), in.getY(), in.getX());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IDFK this just grew and it somehow works. If you understand how, pls tell me.
|
||||||
|
*
|
||||||
|
* @param schemIn give in the original schematic.
|
||||||
|
* @param i index of the Schematic in the schematic placement list.
|
||||||
|
* @return get it out rotated and mirrored.
|
||||||
|
*/
|
||||||
|
public static LitematicaSchematic blackMagicFuckery(LitematicaSchematic schemIn, int i) {
|
||||||
|
LitematicaSchematic tempSchem = schemIn.getCopy(LitematicaHelper.getRotation(i).ordinal() % 2 == 1);
|
||||||
|
for (int yCounter = 0; yCounter < schemIn.getY(); yCounter++) {
|
||||||
|
for (int zCounter = 0; zCounter < schemIn.getZ(); zCounter++) {
|
||||||
|
for (int xCounter = 0; xCounter < schemIn.getX(); xCounter++) {
|
||||||
|
Vec3i xyzHolder = new Vec3i(xCounter, yCounter, zCounter);
|
||||||
|
xyzHolder = LitematicaHelper.doMirroring(xyzHolder, schemIn.getX() - 1, schemIn.getZ() - 1, LitematicaHelper.getMirror(i));
|
||||||
|
for (int turns = 0; turns < LitematicaHelper.getRotation(i).ordinal(); turns++) {
|
||||||
|
if ((turns % 2) == 0) {
|
||||||
|
xyzHolder = LitematicaHelper.rotate(xyzHolder, schemIn.getX() - 1, schemIn.getZ() - 1);
|
||||||
|
} else {
|
||||||
|
xyzHolder = LitematicaHelper.rotate(xyzHolder, schemIn.getZ() - 1, schemIn.getX() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBlockState state = schemIn.getDirect(xCounter, yCounter, zCounter);
|
||||||
|
try {
|
||||||
|
state = state.withMirror(LitematicaHelper.getMirror(i)).withRotation(LitematicaHelper.getRotation(i));
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
//nothing to worry about it's just a hole in the schematic.
|
||||||
|
}
|
||||||
|
tempSchem.setDirect(xyzHolder.getX(), xyzHolder.getY(), xyzHolder.getZ(), state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tempSchem;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* 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 fi.dy.masa.litematica;
|
||||||
|
|
||||||
|
public class Litematica {
|
||||||
|
}
|
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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 fi.dy.masa.litematica.data;
|
||||||
|
|
||||||
|
import fi.dy.masa.litematica.schematic.placement.SchematicPlacementManager;
|
||||||
|
|
||||||
|
public class DataManager {
|
||||||
|
public static final DataManager INSTANCE = new DataManager();
|
||||||
|
private final SchematicPlacementManager schematicPlacementManager = new SchematicPlacementManager();
|
||||||
|
|
||||||
|
private static DataManager getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SchematicPlacementManager getSchematicPlacementManager() {
|
||||||
|
return getInstance().schematicPlacementManager;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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 fi.dy.masa.litematica.schematic.placement;
|
||||||
|
|
||||||
|
import net.minecraft.util.Mirror;
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
|
|
||||||
|
public class SchematicPlacement extends SchematicPlacementUnloaded {
|
||||||
|
private Rotation rotation;
|
||||||
|
private Mirror mirror;
|
||||||
|
|
||||||
|
public Rotation getRotation() {
|
||||||
|
return this.rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mirror getMirror() {
|
||||||
|
return this.mirror;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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 fi.dy.masa.litematica.schematic.placement;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SchematicPlacementManager {
|
||||||
|
private final List<SchematicPlacement> schematicPlacements = new ArrayList<>();
|
||||||
|
|
||||||
|
//in case of a java.lang.NoSuchMethodError try change the name of this method to getAllSchematicPlacements()
|
||||||
|
//there are inconsistencies in the litematica mod about the naming of this method
|
||||||
|
public List<SchematicPlacement> getAllSchematicsPlacements() {
|
||||||
|
return schematicPlacements;
|
||||||
|
}
|
||||||
|
}
|
@@ -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 fi.dy.masa.litematica.schematic.placement;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class SchematicPlacementUnloaded {
|
||||||
|
protected String name = "?";
|
||||||
|
@Nullable
|
||||||
|
protected File schematicFile;
|
||||||
|
protected BlockPos origin = BlockPos.ORIGIN;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public File getSchematicFile() {
|
||||||
|
return this.schematicFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPos getOrigin() {
|
||||||
|
return this.origin;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user