Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for the Structure Block file format (.nbt files) #3317

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/launch/java/baritone/launch/mixins/MixinTemplate.java
Original file line number Diff line number Diff line change
@@ -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 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<Template.BlockInfo> getBlocks();
}
1 change: 1 addition & 0 deletions src/launch/resources/mixins.baritone.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"MixinRenderList",
"MixinStateImplementation",
"MixinTabCompleter",
"MixinTemplate",
"MixinVboRenderList",
"MixinWorldClient"
]
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/baritone/utils/accessor/ITemplate.java
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>.
*/

package baritone.utils.accessor;

import net.minecraft.world.gen.structure.template.Template;

import java.util.List;

public interface ITemplate {

List<Template.BlockInfo> getBlocks();

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 <a href="https://minecraft.fandom.com/wiki/Structure_Block_file_format>Structure Block file format</a>
*/
STRUCTURE("nbt") {
@Override
public IStaticSchematic parse(InputStream input) throws IOException {
return new StructureNBT(CompressedStreamTools.readCompressed(input));
}
};

private final String extension;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* 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.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<Template.BlockInfo> 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<IBlockState> 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;
}
}