Take data directly from Litematica
This commit is contained in:
@@ -39,14 +39,12 @@ import java.util.Optional;
|
||||
* @since 22.09.2022
|
||||
*/
|
||||
public final class LitematicaSchematic extends StaticSchematic {
|
||||
private final Vec3i offsetMinCorner;
|
||||
|
||||
/**
|
||||
* @param nbtTagCompound a decompressed file stream aka nbt data.
|
||||
* @param rotated if the schematic is rotated by 90°.
|
||||
*/
|
||||
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"));
|
||||
@@ -173,6 +171,7 @@ public final class LitematicaSchematic extends StaticSchematic {
|
||||
* reads the file data.
|
||||
*/
|
||||
private void fillInSchematic(CompoundTag nbt) {
|
||||
Vec3i offsetMinCorner = new Vec3i(getMinOfSchematic(nbt, "x"), getMinOfSchematic(nbt, "y"), getMinOfSchematic(nbt, "z"));
|
||||
for (CompoundTag subReg : getRegions(nbt)) {
|
||||
ListTag usedBlockTypes = subReg.getList("BlockStatePalette", 10);
|
||||
BlockState[] blockList = getBlockList(usedBlockTypes);
|
||||
@@ -182,7 +181,7 @@ public final class LitematicaSchematic extends StaticSchematic {
|
||||
long[] blockStateArray = subReg.getLongArray("BlockStates");
|
||||
|
||||
LitematicaBitArray bitArray = new LitematicaBitArray(bitsPerBlock, regionVolume, blockStateArray);
|
||||
writeSubregionIntoSchematic(subReg, blockList, bitArray);
|
||||
writeSubregionIntoSchematic(subReg, offsetMinCorner, blockList, bitArray);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +191,7 @@ 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 subReg, BlockState[] blockList, LitematicaBitArray bitArray) {
|
||||
private void writeSubregionIntoSchematic(CompoundTag subReg, Vec3i offsetMinCorner, 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();
|
||||
@@ -209,13 +208,6 @@ public final class LitematicaSchematic extends StaticSchematic {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return offset from the schematic origin to the minimum Corner as a Vec3i.
|
||||
*/
|
||||
public Vec3i getOffsetMinCorner() {
|
||||
return offsetMinCorner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author maruohon
|
||||
* Class from the Litematica mod by maruohon
|
||||
|
||||
@@ -17,21 +17,27 @@
|
||||
|
||||
package baritone.utils.schematic.litematica;
|
||||
|
||||
import baritone.api.schematic.AbstractSchematic;
|
||||
import baritone.api.schematic.IStaticSchematic;
|
||||
import baritone.api.schematic.ISchematic;
|
||||
import baritone.api.schematic.CompositeSchematic;
|
||||
import baritone.api.schematic.MirroredSchematic;
|
||||
import baritone.api.schematic.RotatedSchematic;
|
||||
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.container.LitematicaBlockStateContainer;
|
||||
import fi.dy.masa.litematica.schematic.placement.SchematicPlacement;
|
||||
import fi.dy.masa.litematica.schematic.placement.SubRegionPlacement;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.util.Tuple;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Helper class that provides access or processes data related to Litmatica schematics.
|
||||
@@ -72,23 +78,6 @@ public final class LitematicaHelper {
|
||||
return getPlacement(i).getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
private static Vec3i getCorrectedOrigin(SchematicPlacement placement, LitematicaSchematic schematic) {
|
||||
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
|
||||
|
||||
Mirror mirror = placement.getMirror();
|
||||
Rotation rotation = placement.getRotation();
|
||||
|
||||
return origin.offset(rotate(doMirroring(minCorner, sx, sz, mirror), sx, sz, rotation));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
@@ -96,7 +85,7 @@ 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.
|
||||
*/
|
||||
private static Vec3i doMirroring(Vec3i in, int sizeX, int sizeZ, Mirror mirror) {
|
||||
static Vec3i doMirroring(Vec3i in, int sizeX, int sizeZ, Mirror mirror) {
|
||||
int xOut = in.getX();
|
||||
int zOut = in.getZ();
|
||||
if (mirror == Mirror.LEFT_RIGHT) {
|
||||
@@ -114,7 +103,7 @@ public final class LitematicaHelper {
|
||||
* @param rotation the rotation to apply
|
||||
* @return the corresponding xyz coordinates after applying {@code rotation}.
|
||||
*/
|
||||
private static Vec3i rotate(Vec3i in, int sizeX, int sizeZ, Rotation rotation) {
|
||||
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());
|
||||
@@ -132,26 +121,91 @@ public final class LitematicaHelper {
|
||||
* @param i index of the Schematic in the schematic placement list.
|
||||
* @return get it out rotated and mirrored.
|
||||
*/
|
||||
public static Tuple<IStaticSchematic, Vec3i> getSchematic(int i) throws IOException {
|
||||
public static Tuple<IStaticSchematic, Vec3i> getSchematic(int i) {
|
||||
// annoying fun fact: you can't just work in placement coordinates and then apply
|
||||
// the placement rotation/mirror to the result because litematica applies the
|
||||
// global transforms *before* applying the local transforms
|
||||
SchematicPlacement placement = getPlacement(i);
|
||||
Rotation rotation = placement.getRotation();
|
||||
Mirror mirror = placement.getMirror();
|
||||
LitematicaSchematic schemIn = new LitematicaSchematic(NbtIo.readCompressed(Files.newInputStream(placement.getSchematicFile().toPath())));
|
||||
Vec3i origin = getCorrectedOrigin(placement, schemIn);
|
||||
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.widthX(), schemIn.lengthZ(), mirror);
|
||||
xyzHolder = rotate(xyzHolder, schemIn.widthX(), schemIn.lengthZ(), rotation);
|
||||
BlockState state = schemIn.getDirect(xCounter, yCounter, zCounter);
|
||||
state = state == null ? null : state.mirror(mirror).rotate(rotation);
|
||||
states[xyzHolder.getX()][xyzHolder.getZ()][xyzHolder.getY()] = state;
|
||||
CompositeSchematic composite = new CompositeSchematic(0, 0, 0);
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int minY = Integer.MAX_VALUE;
|
||||
int minZ = Integer.MAX_VALUE;
|
||||
for (Map.Entry<String, SubRegionPlacement> entry : placement.getEnabledRelativeSubRegionPlacements().entrySet()) {
|
||||
SubRegionPlacement subPlacement = entry.getValue();
|
||||
Vec3i pos = subPlacement.getPos();
|
||||
Vec3i size = placement.getSchematic().getAreaSize(entry.getKey());
|
||||
minX = Math.min(pos.getX() + Math.min(size.getX() + 1, 0), minX);
|
||||
minY = Math.min(pos.getY() + Math.min(size.getY() + 1, 0), minY);
|
||||
minZ = Math.min(pos.getZ() + Math.min(size.getZ() + 1, 0), minZ);
|
||||
}
|
||||
for (Map.Entry<String, SubRegionPlacement> entry : placement.getEnabledRelativeSubRegionPlacements().entrySet()) {
|
||||
SubRegionPlacement subPlacement = entry.getValue();
|
||||
Vec3i size = placement.getSchematic().getAreaSize(entry.getKey());
|
||||
LitematicaBlockStateContainer container = placement.getSchematic().getSubRegionContainer(entry.getKey());
|
||||
BlockState[][][] states = new BlockState[Math.abs(size.getX())][Math.abs(size.getZ())][Math.abs(size.getY())];
|
||||
for (int x = 0; x < states.length; x++) {
|
||||
for (int z = 0; z < states[x].length; z++) {
|
||||
for (int y = 0; y < states[x][z].length; y++) {
|
||||
states[x][z][y] = container.get(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
ISchematic schematic = new StaticSchematic(states);
|
||||
Mirror mirror = subPlacement.getMirror();
|
||||
Rotation rotation = subPlacement.getRotation();
|
||||
if (placement.getRotation() == Rotation.CLOCKWISE_90 || placement.getRotation() == Rotation.COUNTERCLOCKWISE_90) {
|
||||
mirror = mirror == Mirror.LEFT_RIGHT ? Mirror.FRONT_BACK : Mirror.LEFT_RIGHT;
|
||||
}
|
||||
if (placement.getMirror() != Mirror.NONE) {
|
||||
rotation = rotation.getRotated(rotation).getRotated(rotation); // inverse rotation
|
||||
}
|
||||
schematic = new MirroredSchematic(schematic, mirror);
|
||||
schematic = new RotatedSchematic(schematic, rotation);
|
||||
int mx = Math.min(size.getX() + 1, 0);
|
||||
int my = Math.min(size.getY() + 1, 0);
|
||||
int mz = Math.min(size.getZ() + 1, 0);
|
||||
int sx = 2 - Math.abs(size.getX()); // this is because the position needs to be adjusted
|
||||
int sz = 2 - Math.abs(size.getZ()); // by widthX/lengthZ after every transformation
|
||||
Vec3i minCorner = new Vec3i(mx, my, mz);
|
||||
minCorner = rotate(doMirroring(minCorner, sx, sz, mirror), sx, sz, rotation);
|
||||
Vec3i pos = subPlacement.getPos().offset(minCorner).offset(-minX, -minY, -minZ);
|
||||
composite.put(schematic, pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
int sx = 2 - composite.widthX(); // this is because the position needs to be adjusted
|
||||
int sz = 2 - composite.lengthZ(); // by widthX/lengthZ after every transformation
|
||||
Vec3i minCorner = new Vec3i(minX, minY, minZ);
|
||||
Mirror mirror = placement.getMirror();
|
||||
Rotation rotation = placement.getRotation();
|
||||
minCorner = rotate(doMirroring(minCorner, sx, sz, mirror), sx, sz, rotation);
|
||||
ISchematic schematic = new MirroredSchematic(composite, mirror);
|
||||
schematic = new RotatedSchematic(schematic, rotation);
|
||||
return new Tuple<>(new LitematicaPlacementSchematic(schematic), placement.getOrigin().offset(minCorner));
|
||||
}
|
||||
|
||||
private static class LitematicaPlacementSchematic extends AbstractSchematic implements IStaticSchematic {
|
||||
private final ISchematic schematic;
|
||||
|
||||
public LitematicaPlacementSchematic(ISchematic schematic) {
|
||||
super(schematic.widthX(), schematic.heightY(), schematic.lengthZ());
|
||||
this.schematic = schematic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getDirect(int x, int y, int z) {
|
||||
if (inSchematic(x, y, z, null)) {
|
||||
return desiredState(x, y, z, null, Collections.emptyList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState desiredState(int x, int y, int z, BlockState current, List<BlockState> approxPlaceable) {
|
||||
return schematic.desiredState(x, y, z, current, approxPlaceable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inSchematic(int x, int y, int z, BlockState current) {
|
||||
return schematic.inSchematic(x, y, z, current);
|
||||
}
|
||||
return new Tuple<>(new StaticSchematic(states), origin);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user