Shorten / simplify some Litematica related things

This commit is contained in:
ZacSharp
2024-07-27 21:26:17 +02:00
parent edb433ea6e
commit 330089f1e2
11 changed files with 115 additions and 244 deletions

View File

@@ -34,18 +34,9 @@ public class LitematicaCommand extends Command {
@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.");
}
args.requireMax(1);
int schematic = args.hasAny() ? args.getAs(Integer.class) - 1 : 0;
baritone.getBuilderProcess().buildOpenLitematic(schematic);
}
@Override

View File

@@ -227,12 +227,7 @@ public class SelCommand extends Command {
}
}
}
ISchematic schematic = new StaticSchematic() {{
states = blockstates;
x = size.getX();
y = size.getY();
z = size.getZ();
}};
ISchematic schematic = new StaticSchematic(blockstates);
composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z);
}
clipboard = composite;

View File

@@ -229,19 +229,19 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
public void buildOpenLitematic(int i) {
if (LitematicaHelper.isLitematicaPresent()) {
//if java.lang.NoSuchMethodError is thrown see comment in SchematicPlacementManager
if (LitematicaHelper.hasLoadedSchematic()) {
if (LitematicaHelper.hasLoadedSchematic(i)) {
String name = LitematicaHelper.getName(i);
try {
LitematicaSchematic schematic1 = new LitematicaSchematic(NbtIo.readCompressed(Files.newInputStream(LitematicaHelper.getSchematicFile(i).toPath())), false);
LitematicaSchematic schematic1 = new LitematicaSchematic(NbtIo.readCompressed(Files.newInputStream(LitematicaHelper.getSchematicFile(i).toPath())));
Vec3i correctedOrigin = LitematicaHelper.getCorrectedOrigin(schematic1, i);
ISchematic schematic2 = LitematicaHelper.blackMagicFuckery(schematic1, i);
ISchematic schematic2 = LitematicaHelper.applyPlacementRotation(schematic1, i);
schematic2 = applyMapArtAndSelection(origin, (IStaticSchematic) schematic2);
build(name, schematic2, correctedOrigin);
} catch (Exception e) {
logDirect("Schematic File could not be loaded.");
}
} else {
logDirect("No schematic currently loaded");
logDirect(String.format("List of placements has no entry %s", i + 1));
}
} else {
logDirect("Litematica is not present");

View File

@@ -32,6 +32,16 @@ public class StaticSchematic extends AbstractSchematic implements IStaticSchemat
protected BlockState[][][] states;
public StaticSchematic() {}
public StaticSchematic(BlockState[][][] states) {
this.states = states;
boolean empty = states.length == 0 || states[0].length == 0 || states[0][0].length == 0;
this.x = empty ? 0 : states.length;
this.z = empty ? 0 : states[0].length;
this.y = empty ? 0 : states[0][0].length;
}
@Override
public BlockState desiredState(int x, int y, int z, BlockState current, List<BlockState> approxPlaceable) {
return this.states[x][z][y];

View File

@@ -81,7 +81,7 @@ public enum DefaultSchematicFormats implements ISchematicFormat {
case 5: //1.13-1.17
throw new UnsupportedOperationException("This litematic Version is too old.");
case 6: //1.18+
return new LitematicaSchematic(nbt, false);
return new LitematicaSchematic(nbt);
default:
throw new UnsupportedOperationException("Unsuported Version of a Litematica Schematic");
}

View File

@@ -18,7 +18,6 @@
package baritone.utils.schematic.format.defaults;
import baritone.utils.schematic.StaticSchematic;
import net.minecraft.core.Registry;
import net.minecraft.core.Vec3i;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
@@ -41,33 +40,28 @@ import java.util.Optional;
*/
public final class LitematicaSchematic extends StaticSchematic {
private final Vec3i offsetMinCorner;
private final CompoundTag nbt;
/**
* @param nbtTagCompound a decompressed file stream aka nbt data.
* @param rotated if the schematic is rotated by 90°.
*/
public LitematicaSchematic(CompoundTag nbtTagCompound, boolean rotated) {
this.nbt = nbtTagCompound;
this.offsetMinCorner = new Vec3i(getMinOfSchematic("x"), getMinOfSchematic("y"), getMinOfSchematic("z"));
this.y = Math.abs(nbt.getCompound("Metadata").getCompound("EnclosingSize").getInt("y"));
if (rotated) {
this.x = Math.abs(nbt.getCompound("Metadata").getCompound("EnclosingSize").getInt("z"));
this.z = Math.abs(nbt.getCompound("Metadata").getCompound("EnclosingSize").getInt("x"));
} else {
this.x = Math.abs(nbt.getCompound("Metadata").getCompound("EnclosingSize").getInt("x"));
this.z = Math.abs(nbt.getCompound("Metadata").getCompound("EnclosingSize").getInt("z"));
}
public LitematicaSchematic(CompoundTag nbt) {
this.offsetMinCorner = new Vec3i(getMinOfSchematic(nbt, "x"), getMinOfSchematic(nbt, "y"), getMinOfSchematic(nbt, "z"));
CompoundTag size = nbt.getCompound("Metadata").getCompound("EnclosingSize");
this.x = Math.abs(size.getInt("x"));
this.y = Math.abs(size.getInt("y"));
this.z = Math.abs(size.getInt("z"));
this.states = new BlockState[this.x][this.z][this.y];
fillInSchematic();
fillInSchematic(nbt);
}
/**
* @return Array of subregion names.
* @return Array of subregion tags.
*/
private static String[] getRegions(CompoundTag nbt) {
return nbt.getCompound("Regions").getAllKeys().toArray(new String[0]);
private static CompoundTag[] getRegions(CompoundTag nbt) {
return nbt.getCompound("Regions").getAllKeys().stream()
.map(nbt.getCompound("Regions")::getCompound)
.toArray(CompoundTag[]::new);
}
/**
@@ -76,14 +70,10 @@ public final class LitematicaSchematic extends StaticSchematic {
* @param s axis that should be read.
* @return the lower coord of the requested axis.
*/
private static int getMinOfSubregion(CompoundTag nbt, String subReg, String s) {
int a = nbt.getCompound("Regions").getCompound(subReg).getCompound("Position").getInt(s);
int b = nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt(s);
if (b < 0) {
b++;
}
return Math.min(a, a + b);
private static int getMinOfSubregion(CompoundTag subReg, String s) {
int a = subReg.getCompound("Position").getInt(s);
int b = subReg.getCompound("Size").getInt(s);
return Math.min(a, a + b + 1);
}
/**
@@ -110,7 +100,7 @@ public final class LitematicaSchematic extends StaticSchematic {
private static BlockState getBlockState(Block block, CompoundTag properties) {
BlockState blockState = block.defaultBlockState();
for (Object key : properties.getAllKeys().toArray()) {
for (Object key : properties.getAllKeys()) {
Property<?> property = block.getStateDefinition().getProperty((String) key);
String propertyValue = properties.getString((String) key);
if (property != null) {
@@ -146,18 +136,9 @@ public final class LitematicaSchematic extends StaticSchematic {
*
* @return the volume of the subregion.
*/
private static long getVolume(CompoundTag nbt, String subReg) {
return Math.abs(
nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("x") *
nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("y") *
nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("z"));
}
/**
* @return array of Long values.
*/
private static long[] getBlockStates(CompoundTag nbt, String subReg) {
return nbt.getCompound("Regions").getCompound(subReg).getLongArray("BlockStates");
private static long getVolume(CompoundTag subReg) {
CompoundTag size = subReg.getCompound("Size");
return Math.abs(size.getInt("x") * size.getInt("y") * size.getInt("z"));
}
/**
@@ -168,21 +149,22 @@ public final class LitematicaSchematic extends StaticSchematic {
* @param z coord of the block relative to the minimum corner.
* @return if the current block is part of the subregion.
*/
private static boolean inSubregion(CompoundTag nbt, String subReg, int x, int y, int z) {
private static boolean inSubregion(CompoundTag subReg, int x, int y, int z) {
CompoundTag size = subReg.getCompound("Size");
return x >= 0 && y >= 0 && z >= 0 &&
x < Math.abs(nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("x")) &&
y < Math.abs(nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("y")) &&
z < Math.abs(nbt.getCompound("Regions").getCompound(subReg).getCompound("Size").getInt("z"));
x < Math.abs(size.getInt("x")) &&
y < Math.abs(size.getInt("y")) &&
z < Math.abs(size.getInt("z"));
}
/**
* @param s axis.
* @return the lowest coordinate of that axis of the schematic.
*/
private int getMinOfSchematic(String s) {
private static int getMinOfSchematic(CompoundTag nbt, String s) {
int n = Integer.MAX_VALUE;
for (String subReg : getRegions(nbt)) {
n = Math.min(n, getMinOfSubregion(nbt, subReg, s));
for (CompoundTag subReg : getRegions(nbt)) {
n = Math.min(n, getMinOfSubregion(subReg, s));
}
return n;
}
@@ -190,18 +172,17 @@ public final class LitematicaSchematic extends StaticSchematic {
/**
* reads the file data.
*/
private void fillInSchematic() {
for (String subReg : getRegions(nbt)) {
ListTag usedBlockTypes = nbt.getCompound("Regions").getCompound(subReg).getList("BlockStatePalette", 10);
private void fillInSchematic(CompoundTag nbt) {
for (CompoundTag subReg : getRegions(nbt)) {
ListTag usedBlockTypes = subReg.getList("BlockStatePalette", 10);
BlockState[] blockList = getBlockList(usedBlockTypes);
int bitsPerBlock = getBitsPerBlock(usedBlockTypes.size());
long regionVolume = getVolume(nbt, subReg);
long[] blockStateArray = getBlockStates(nbt, subReg);
long regionVolume = getVolume(subReg);
long[] blockStateArray = subReg.getLongArray("BlockStates");
LitematicaBitArray bitArray = new LitematicaBitArray(bitsPerBlock, regionVolume, blockStateArray);
writeSubregionIntoSchematic(nbt, subReg, blockList, bitArray);
writeSubregionIntoSchematic(subReg, blockList, bitArray);
}
}
@@ -211,14 +192,16 @@ public final class LitematicaSchematic extends StaticSchematic {
* @param blockList list with the different block types used in the schematic.
* @param bitArray bit array that holds the placement pattern.
*/
private void writeSubregionIntoSchematic(CompoundTag nbt, String subReg, BlockState[] blockList, LitematicaBitArray bitArray) {
Vec3i offsetSubregion = new Vec3i(getMinOfSubregion(nbt, subReg, "x"), getMinOfSubregion(nbt, subReg, "y"), getMinOfSubregion(nbt, subReg, "z"));
private void writeSubregionIntoSchematic(CompoundTag subReg, BlockState[] blockList, LitematicaBitArray bitArray) {
int offsetX = getMinOfSubregion(subReg, "x") - offsetMinCorner.getX();
int offsetY = getMinOfSubregion(subReg, "y") - offsetMinCorner.getY();
int offsetZ = getMinOfSubregion(subReg, "z") - offsetMinCorner.getZ();
int index = 0;
for (int y = 0; y < this.y; y++) {
for (int z = 0; z < this.z; z++) {
for (int x = 0; x < this.x; x++) {
if (inSubregion(nbt, subReg, x, y, z)) {
this.states[x - (offsetMinCorner.getX() - offsetSubregion.getX())][z - (offsetMinCorner.getZ() - offsetSubregion.getZ())][y - (offsetMinCorner.getY() - offsetSubregion.getY())] = blockList[bitArray.getAt(index)];
if (inSubregion(subReg, x, y, z)) {
this.states[x + offsetX][z + offsetZ][y + offsetY] = blockList[bitArray.getAt(index)];
index++;
}
}
@@ -233,45 +216,6 @@ public final class LitematicaSchematic extends StaticSchematic {
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, BlockState 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
* Class from the Litematica mod by maruohon

View File

@@ -17,9 +17,11 @@
package baritone.utils.schematic.litematica;
import baritone.utils.schematic.StaticSchematic;
import baritone.utils.schematic.format.defaults.LitematicaSchematic;
import fi.dy.masa.litematica.Litematica;
import fi.dy.masa.litematica.data.DataManager;
import fi.dy.masa.litematica.schematic.placement.SchematicPlacement;
import net.minecraft.core.Vec3i;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
@@ -48,10 +50,14 @@ public final class LitematicaHelper {
}
/**
* @return if there are loaded schematics.
* @return if {@code i} is a valid placement index
*/
public static boolean hasLoadedSchematic() {
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().size() > 0;
public static boolean hasLoadedSchematic(int i) {
return 0 <= i && i < DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().size();
}
private static SchematicPlacement getPlacement(int i) {
return DataManager.getSchematicPlacementManager().getAllSchematicsPlacements().get(i);
}
/**
@@ -59,15 +65,7 @@ public final class LitematicaHelper {
* @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();
return getPlacement(i).getName();
}
/**
@@ -75,23 +73,7 @@ public final class LitematicaHelper {
* @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();
return getPlacement(i).getSchematicFile();
}
/**
@@ -100,55 +82,16 @@ public final class LitematicaHelper {
* @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;
SchematicPlacement placement = getPlacement(i);
Vec3i origin = placement.getOrigin();
Vec3i minCorner = schematic.getOffsetMinCorner();
int sx = 2 - schematic.widthX(); // this is because the position needs to be adjusted
int sz = 2 - schematic.lengthZ(); // by widthX/lengthZ after every transformation
Vec3i correctedOrigin;
Mirror mirror = LitematicaHelper.getMirror(i);
Rotation rotation = LitematicaHelper.getRotation(i);
Mirror mirror = placement.getMirror();
Rotation rotation = placement.getRotation();
//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;
return origin.offset(rotate(doMirroring(minCorner, sx, sz, mirror), sx, sz, rotation));
}
/**
@@ -158,13 +101,13 @@ public final class LitematicaHelper {
* @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) {
private 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();
zOut = sizeZ - 1 - in.getZ();
} else if (mirror == Mirror.FRONT_BACK) {
xOut = sizeX - in.getX();
xOut = sizeX - 1 - in.getX();
}
return new Vec3i(xOut, in.getY(), zOut);
}
@@ -173,43 +116,45 @@ public final class LitematicaHelper {
* @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.
* @param rotation the rotation to apply
* @return the corresponding xyz coordinates after applying {@code rotation}.
*/
public static Vec3i rotate(Vec3i in, int sizeX, int sizeZ) {
return new Vec3i(sizeX - (sizeX - sizeZ) - in.getZ(), in.getY(), in.getX());
private static Vec3i rotate(Vec3i in, int sizeX, int sizeZ, Rotation rotation) {
switch (rotation) {
case CLOCKWISE_90:
return new Vec3i(sizeZ - 1 - in.getZ(), in.getY(), in.getX());
case CLOCKWISE_180:
return new Vec3i(sizeX - 1 - in.getX(), in.getY(), sizeZ - 1 - in.getZ());
case COUNTERCLOCKWISE_90:
return new Vec3i(in.getZ(), in.getY(), sizeX - 1 - in.getX());
default:
return in;
}
}
/**
* 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++) {
public static StaticSchematic applyPlacementRotation(LitematicaSchematic schemIn, int i) {
SchematicPlacement placement = getPlacement(i);
Rotation rotation = placement.getRotation();
Mirror mirror = placement.getMirror();
boolean flip = rotation == Rotation.CLOCKWISE_90 || rotation == Rotation.COUNTERCLOCKWISE_90;
BlockState[][][] states = new BlockState[flip ? schemIn.lengthZ() : schemIn.widthX()][flip ? schemIn.widthX() : schemIn.lengthZ()][schemIn.heightY()];
for (int yCounter = 0; yCounter < schemIn.heightY(); yCounter++) {
for (int zCounter = 0; zCounter < schemIn.lengthZ(); zCounter++) {
for (int xCounter = 0; xCounter < schemIn.widthX(); 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);
}
}
xyzHolder = LitematicaHelper.doMirroring(xyzHolder, schemIn.widthX(), schemIn.lengthZ(), mirror);
xyzHolder = rotate(xyzHolder, schemIn.widthX(), schemIn.lengthZ(), rotation);
BlockState state = schemIn.getDirect(xCounter, yCounter, zCounter);
try {
state = state.mirror(LitematicaHelper.getMirror(i)).rotate(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);
state = state == null ? null : state.mirror(mirror).rotate(rotation);
states[xyzHolder.getX()][xyzHolder.getZ()][xyzHolder.getY()] = state;
}
}
}
return tempSchem;
return new StaticSchematic(states);
}
}