diff --git a/src/launch/java/baritone/launch/mixins/MixinTemplate.java b/src/launch/java/baritone/launch/mixins/MixinTemplate.java
new file mode 100644
index 000000000..7019aac74
--- /dev/null
+++ b/src/launch/java/baritone/launch/mixins/MixinTemplate.java
@@ -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 .
+ */
+
+package baritone.launch.mixins;
+
+import baritone.utils.accessor.ITemplate;
+import net.minecraft.world.gen.structure.template.Template;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import java.util.List;
+
+@Mixin(Template.class)
+public abstract class MixinTemplate implements ITemplate {
+
+ @Override
+ @Accessor
+ public abstract List getBlocks();
+}
diff --git a/src/launch/resources/mixins.baritone.json b/src/launch/resources/mixins.baritone.json
index fdcd14b92..632b16df6 100644
--- a/src/launch/resources/mixins.baritone.json
+++ b/src/launch/resources/mixins.baritone.json
@@ -30,6 +30,7 @@
"MixinRenderList",
"MixinStateImplementation",
"MixinTabCompleter",
+ "MixinTemplate",
"MixinVboRenderList",
"MixinWorldClient"
]
diff --git a/src/main/java/baritone/utils/accessor/ITemplate.java b/src/main/java/baritone/utils/accessor/ITemplate.java
new file mode 100644
index 000000000..c71bae70b
--- /dev/null
+++ b/src/main/java/baritone/utils/accessor/ITemplate.java
@@ -0,0 +1,28 @@
+/*
+ * 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 .
+ */
+
+package baritone.utils.accessor;
+
+import net.minecraft.world.gen.structure.template.Template;
+
+import java.util.List;
+
+public interface ITemplate {
+
+ List getBlocks();
+
+}
diff --git a/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java b/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java
index fb20164bd..2d2736a00 100644
--- a/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java
+++ b/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java
@@ -21,6 +21,7 @@
import baritone.api.schematic.format.ISchematicFormat;
import baritone.utils.schematic.format.defaults.MCEditSchematic;
import baritone.utils.schematic.format.defaults.SpongeSchematic;
+import baritone.utils.schematic.format.defaults.StructureNBT;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import org.apache.commons.io.FilenameUtils;
@@ -65,6 +66,18 @@ public IStaticSchematic parse(InputStream input) throws IOException {
throw new UnsupportedOperationException("Unsupported Version of a Sponge Schematic");
}
}
+ },
+
+ /**
+ * The vanilla structure block file format. Commonly denoted by the ".nbt" file extension.
+ *
+ * @see .
+ */
+
+package baritone.utils.schematic.format.defaults;
+
+import baritone.utils.accessor.ITemplate;
+import baritone.utils.schematic.StaticSchematic;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.init.Blocks;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.gen.structure.template.Template;
+
+import java.util.List;
+
+/**
+ * @author Sam
+ * @since 03/11/2022
+ */
+public final class StructureNBT extends StaticSchematic {
+
+ public StructureNBT(NBTTagCompound schematic) {
+ Template template = new Template();
+ template.read(schematic);
+
+ BlockPos size = template.getSize();
+ this.x = size.getX();
+ this.y = size.getY();
+ this.z = size.getZ();
+
+ List blocks = ((ITemplate) template).getBlocks();
+ this.states = new IBlockState[this.x][this.z][this.y];
+ for (Template.BlockInfo block : blocks) {
+ this.states[block.pos.getX()][block.pos.getZ()][block.pos.getY()] = block.blockState;
+ }
+ }
+
+ @Override
+ public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) {
+ IBlockState block = this.states[x][z][y];
+ return block != null ? block : current;
+ }
+
+ @Override
+ public IBlockState getDirect(int x, int y, int z) {
+ // Use air blocks as placeholder for Structure Void
+ return desiredState(x, y, z, Blocks.AIR.getDefaultState(), null);
+ }
+
+ @Override
+ public IBlockState[] getColumn(int x, int z) {
+ IBlockState[] column = this.states[x][z].clone();
+ for (int i = 0; i < column.length; i++) {
+ // Use air blocks as placeholder for Structure Void
+ if (column[i] == null) {
+ column[i] = Blocks.AIR.getDefaultState();
+ }
+ }
+ return column;
+ }
+
+ @Override
+ public boolean inSchematic(int x, int y, int z, IBlockState currentState) {
+ // Filtering out Structure Void
+ return super.inSchematic(x, y, z, currentState) && this.states[x][z][y] != null;
+ }
+}