diff --git a/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeSchematicAddon.java b/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeSchematicAddon.java index caf7f47b5..ab27f3e2d 100644 --- a/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeSchematicAddon.java +++ b/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeSchematicAddon.java @@ -30,6 +30,7 @@ import com.dfsek.terra.api.inject.annotations.Inject; import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.structure.Structure; import com.dfsek.terra.api.util.StringUtil; +import com.dfsek.terra.api.util.vector.Vector3Int; public class SpongeSchematicAddon implements AddonInitializer { @@ -75,6 +76,25 @@ public class SpongeSchematicAddon implements AddonInitializer { int len = baseTag.getShort("Length"); int hei = baseTag.getShort("Height"); + CompoundTag metadata = baseTag.getCompoundTag("Metadata"); + + Vector3Int offset; + // Use WorldEdit relative offset if it exists in schematic metadata + IntTag worldEditOffsetX = metadata.getIntTag("WEOffsetX"); + IntTag worldEditOffsetY = metadata.getIntTag("WEOffsetY"); + IntTag worldEditOffsetZ = metadata.getIntTag("WEOffsetZ"); + if (worldEditOffsetX != null || worldEditOffsetY != null || worldEditOffsetZ != null) { + if (worldEditOffsetX == null || worldEditOffsetY == null || worldEditOffsetZ == null) { + throw new IllegalArgumentException("Failed to parse Sponge schematic: Malformed WorldEdit offset"); + } + offset = Vector3Int.of(worldEditOffsetX.asInt(), worldEditOffsetY.asInt(), worldEditOffsetZ.asInt()); + } else { + // Set offset based on the 'Offset' field, not clear on if this is correct behaviour according to spec so left commented for now + //int[] offsetArray = baseTag.getIntArray("Offset"); + //offset = Vector3Int.of(offsetArray[0], offsetArray[1], offsetArray[2]); + offset = Vector3Int.zero(); + } + ByteArrayTag blocks = baseTag.getByteArrayTag("BlockData"); CompoundTag palette = (CompoundTag) baseTag.get("Palette"); @@ -97,7 +117,7 @@ public class SpongeSchematicAddon implements AddonInitializer { } } - return new SpongeStructure(states, addon.key(id)); + return new SpongeStructure(states, offset, addon.key(id)); } catch(IOException e) { throw new IllegalArgumentException("Failed to parse Sponge schematic: ", e); } diff --git a/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java b/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java index e08c51146..49bde23fb 100644 --- a/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java +++ b/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java @@ -23,10 +23,15 @@ public class SpongeStructure implements Structure, Keyed { private final BlockState[][][] blocks; + private final int offsetX, offsetY, offsetZ; + private final RegistryKey id; - public SpongeStructure(BlockState[][][] blocks, RegistryKey id) { + public SpongeStructure(BlockState[][][] blocks, Vector3Int offset, RegistryKey id) { this.blocks = blocks; + this.offsetX = offset.getX(); + this.offsetY = offset.getY(); + this.offsetZ = offset.getZ(); this.id = id; } @@ -37,13 +42,15 @@ public class SpongeStructure implements Structure, Keyed { int bZ = location.getZ(); for(int x = 0; x < blocks.length; x++) { for(int z = 0; z < blocks[x].length; z++) { - Vector2Int r = Vector2Int.of(x, z).rotate(rotation); + int oX = x + offsetX; + int oZ = z + offsetZ; + Vector2Int r = Vector2Int.of(oX, oZ).rotate(rotation); int rX = r.getX(); int rZ = r.getZ(); for(int y = 0; y < blocks[x][z].length; y++) { BlockState state = blocks[x][z][y]; if(state == null) continue; - world.setBlockState(bX + rX, bY + y, bZ + rZ, state); + world.setBlockState(bX + rX, bY + y + offsetY, bZ + rZ, state); } } }