fix: schematic versions
This commit is contained in:
parent
e6788d529a
commit
6ab167e7db
5 changed files with 59 additions and 22 deletions
|
|
@ -12,8 +12,8 @@ const versions = [
|
|||
"1.21.4",
|
||||
"1.21",
|
||||
"1.20",
|
||||
"1.18",
|
||||
"1.19",
|
||||
"1.18",
|
||||
"1.17",
|
||||
"1.16",
|
||||
"1.15",
|
||||
|
|
|
|||
|
|
@ -7,18 +7,24 @@ import * as nbt from "nbtify";
|
|||
import { CanvasContext } from "@/context/Canvas";
|
||||
import { LoadingContext } from "@/context/Loading";
|
||||
|
||||
import { decodeVarint } from "@/utils/varint";
|
||||
|
||||
import { DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
import _blockData from "@/data/blocks/data.json";
|
||||
const blockData: BlockData = _blockData;
|
||||
|
||||
import _versionData from "@/data/versions.json";
|
||||
const versionData: Record<string, number> = _versionData;
|
||||
|
||||
interface LitematicaBlockPalette extends nbt.CompoundTagLike {
|
||||
Name: string;
|
||||
Properties?: Record<string, string>;
|
||||
}
|
||||
|
||||
interface LitematicNBT extends nbt.ListTagLike {
|
||||
MinecraftDataVersion: number;
|
||||
Regions: {
|
||||
Image: {
|
||||
BlockStatePalette: LitematicaBlockPalette[];
|
||||
|
|
@ -34,13 +40,14 @@ interface SpongeNBT extends nbt.ListTagLike {
|
|||
Data: Int8Array;
|
||||
Palette: Record<string, number>;
|
||||
};
|
||||
DataVersion: number;
|
||||
Width: number;
|
||||
Height: number;
|
||||
};
|
||||
}
|
||||
|
||||
function OpenSchematic({ close }: DialogProps) {
|
||||
const { setBlocks } = useContext(CanvasContext);
|
||||
const { setBlocks, setVersion } = useContext(CanvasContext);
|
||||
const { setLoading } = useContext(LoadingContext);
|
||||
|
||||
const { acceptedFiles, getRootProps, getInputProps } = useDropzone({
|
||||
|
|
@ -61,16 +68,20 @@ function OpenSchematic({ close }: DialogProps) {
|
|||
const data = await nbt.read(bytes);
|
||||
|
||||
if (fileExtension == "litematic") {
|
||||
const litematicData = (data as nbt.NBTData<LitematicNBT>).data.Regions.Image;
|
||||
const litematicData = (data as nbt.NBTData<LitematicNBT>).data;
|
||||
const litematicRegionData = litematicData.Regions.Image;
|
||||
const litematicVersion = Object.keys(versionData).find((key) => versionData[key] == litematicData.MinecraftDataVersion);
|
||||
|
||||
// todo: set version
|
||||
const requiredBits = Math.max(Math.ceil(Math.log2(litematicData.BlockStatePalette.length)), 2);
|
||||
// Set version to schematic version. If it doesn't find it in the data, return the latest version
|
||||
setVersion(parseInt(litematicVersion || Object.keys(versionData)[0]));
|
||||
|
||||
const requiredBits = Math.max(Math.ceil(Math.log2(litematicRegionData.BlockStatePalette.length)), 2);
|
||||
|
||||
const getPaletteIndex = (index: number): bigint => {
|
||||
const originalY = Math.floor(index / litematicData.Size.x);
|
||||
const originalX = index % litematicData.Size.x;
|
||||
const reversedY = litematicData.Size.y - 1 - originalY;
|
||||
const reversedIndex = reversedY * litematicData.Size.x + originalX;
|
||||
const originalY = Math.floor(index / litematicRegionData.Size.x);
|
||||
const originalX = index % litematicRegionData.Size.x;
|
||||
const reversedY = litematicRegionData.Size.y - 1 - originalY;
|
||||
const reversedIndex = reversedY * litematicRegionData.Size.x + originalX;
|
||||
|
||||
// getAt() implementation - LitematicaBitArray.java
|
||||
const startOffset = reversedIndex * requiredBits;
|
||||
|
|
@ -80,11 +91,12 @@ function OpenSchematic({ close }: DialogProps) {
|
|||
const mask = (1 << requiredBits) - 1;
|
||||
|
||||
if (startArrayIndex === endArrayIndex) {
|
||||
return (litematicData.BlockStates[startArrayIndex] >> BigInt(bitOffset)) & BigInt(mask);
|
||||
return (litematicRegionData.BlockStates[startArrayIndex] >> BigInt(bitOffset)) & BigInt(mask);
|
||||
} else {
|
||||
const endOffset = 64 - bitOffset;
|
||||
return (
|
||||
((litematicData.BlockStates[startArrayIndex] >> BigInt(bitOffset)) | (litematicData.BlockStates[endArrayIndex] << BigInt(endOffset))) &
|
||||
((litematicRegionData.BlockStates[startArrayIndex] >> BigInt(bitOffset)) |
|
||||
(litematicRegionData.BlockStates[endArrayIndex] << BigInt(endOffset))) &
|
||||
BigInt(mask)
|
||||
);
|
||||
}
|
||||
|
|
@ -94,11 +106,11 @@ function OpenSchematic({ close }: DialogProps) {
|
|||
const blocks: Block[] = [];
|
||||
let index = 0;
|
||||
|
||||
for (let y = 0; y < litematicData.Size.y; y++) {
|
||||
for (let x = 0; x < litematicData.Size.x; x++) {
|
||||
for (let y = 0; y < litematicRegionData.Size.y; y++) {
|
||||
for (let x = 0; x < litematicRegionData.Size.x; x++) {
|
||||
const paletteIndex = Number(getPaletteIndex(index));
|
||||
console.log(paletteIndex);
|
||||
const paletteBlock = litematicData.BlockStatePalette[paletteIndex];
|
||||
const paletteBlock = litematicRegionData.BlockStatePalette[paletteIndex];
|
||||
|
||||
index++;
|
||||
if (!paletteBlock) continue;
|
||||
|
|
@ -134,7 +146,10 @@ function OpenSchematic({ close }: DialogProps) {
|
|||
setBlocks(blocks);
|
||||
} else if (fileExtension == "schem") {
|
||||
const spongeData = (data as nbt.NBTData<SpongeNBT>).data.Schematic;
|
||||
// todo: set version
|
||||
const schematicVersion = Object.keys(versionData).find((key) => versionData[key] == spongeData.DataVersion);
|
||||
|
||||
// Set version to schematic version. If it doesn't find it in the data, return the latest version
|
||||
setVersion(parseInt(schematicVersion || Object.keys(versionData)[0]));
|
||||
|
||||
// Add every block to the canvas
|
||||
const blocks: Block[] = [];
|
||||
|
|
|
|||
|
|
@ -11,8 +11,11 @@ import { Input } from "@/components/ui/input";
|
|||
import _blockData from "@/data/blocks/data.json";
|
||||
const blockData: BlockData = _blockData;
|
||||
|
||||
import _versionData from "@/data/versions.json";
|
||||
const versionData: Record<string, number> = _versionData;
|
||||
|
||||
function SaveLitematic({ close }: DialogProps) {
|
||||
const { canvasSize, blocks } = useContext(CanvasContext);
|
||||
const { canvasSize, blocks, version } = useContext(CanvasContext);
|
||||
const { setLoading } = useContext(LoadingContext);
|
||||
|
||||
const [fileName, setFileName] = useState("blockmatic");
|
||||
|
|
@ -92,7 +95,7 @@ function SaveLitematic({ close }: DialogProps) {
|
|||
|
||||
// Generate NBT data
|
||||
const data = {
|
||||
MinecraftDataVersion: new nbt.Int32(4189),
|
||||
MinecraftDataVersion: new nbt.Int32(versionData[version]),
|
||||
Version: new nbt.Int32(7),
|
||||
SubVersion: new nbt.Int32(1),
|
||||
Metadata: {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ import { Input } from "@/components/ui/input";
|
|||
import _blockData from "@/data/blocks/data.json";
|
||||
const blockData: BlockData = _blockData;
|
||||
|
||||
import _versionData from "@/data/versions.json";
|
||||
const versionData: Record<string, number> = _versionData;
|
||||
|
||||
interface BlockEntity {
|
||||
Id: string;
|
||||
Pos: Int32Array;
|
||||
|
|
@ -40,8 +43,8 @@ const blockEntitiesWhitelist = [
|
|||
"vault",
|
||||
];
|
||||
|
||||
function SaveLitematic({ close }: DialogProps) {
|
||||
const { canvasSize, blocks } = useContext(CanvasContext);
|
||||
function SaveSchem({ close }: DialogProps) {
|
||||
const { canvasSize, blocks, version } = useContext(CanvasContext);
|
||||
const { setLoading } = useContext(LoadingContext);
|
||||
|
||||
const [fileName, setFileName] = useState("blockmatic");
|
||||
|
|
@ -130,7 +133,7 @@ function SaveLitematic({ close }: DialogProps) {
|
|||
// Generate NBT data
|
||||
const data = {
|
||||
Schematic: {
|
||||
DataVersion: new nbt.Int32(4189),
|
||||
DataVersion: new nbt.Int32(versionData[version]),
|
||||
Version: new nbt.Int32(3),
|
||||
Width: new nbt.Int16(width),
|
||||
Height: new nbt.Int16(height),
|
||||
|
|
@ -167,7 +170,7 @@ function SaveLitematic({ close }: DialogProps) {
|
|||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Save as .schem</DialogTitle>
|
||||
<DialogDescription>Save your image as a .schem (Sponge)</DialogDescription>
|
||||
<DialogDescription>Save your image as a .schem (Sponge Version 3)</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
|
|
@ -187,4 +190,4 @@ function SaveLitematic({ close }: DialogProps) {
|
|||
);
|
||||
}
|
||||
|
||||
export default SaveLitematic;
|
||||
export default SaveSchem;
|
||||
|
|
|
|||
16
src/data/versions.json
Normal file
16
src/data/versions.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"1214": 4189,
|
||||
"1210": 3953,
|
||||
"1200": 3463,
|
||||
"1190": 3105,
|
||||
"1180": 2860,
|
||||
"1170": 2724,
|
||||
"1160": 2566,
|
||||
"1150": 2225,
|
||||
"1140": 1952,
|
||||
"1130": 1519,
|
||||
"1120": 1139,
|
||||
"1110": 819,
|
||||
"1000": 510,
|
||||
"1090": 169
|
||||
}
|
||||
Loading…
Reference in a new issue