Style: Modularise LvlFile.

This commit is contained in:
UnknownShadow200 2016-09-17 15:16:13 +10:00
parent f58cb2d07b
commit 2f2e856199

View File

@ -25,25 +25,32 @@ namespace MCGalaxy.Levels.IO {
//You MUST make it able to save and load as a new version other wise you will make old levels incompatible! //You MUST make it able to save and load as a new version other wise you will make old levels incompatible!
public static class LvlFile { public static class LvlFile {
public static void Save(Level level, string file) { public static void Save(Level lvl, string file) {
using (Stream fs = File.Create(file)) using (Stream fs = File.Create(file), gs = new GZipStream(fs, CompressionMode.Compress, true)) {
using (Stream gs = new GZipStream(fs, CompressionMode.Compress, true)) WriteHeader(lvl, gs);
{ WriteBlocksSection(lvl, gs);
WriteBlockDefsSection(lvl, gs);
}
}
static void WriteHeader(Level lvl, Stream gs) {
byte[] header = new byte[18]; byte[] header = new byte[18];
BitConverter.GetBytes(1874).CopyTo(header, 0); BitConverter.GetBytes(1874).CopyTo(header, 0);
BitConverter.GetBytes(level.Width).CopyTo(header, 2); BitConverter.GetBytes(lvl.Width).CopyTo(header, 2);
BitConverter.GetBytes(level.Length).CopyTo(header, 4); BitConverter.GetBytes(lvl.Length).CopyTo(header, 4);
BitConverter.GetBytes(level.Height).CopyTo(header, 6); BitConverter.GetBytes(lvl.Height).CopyTo(header, 6);
BitConverter.GetBytes(level.spawnx).CopyTo(header, 8); BitConverter.GetBytes(lvl.spawnx).CopyTo(header, 8);
BitConverter.GetBytes(level.spawnz).CopyTo(header, 10); BitConverter.GetBytes(lvl.spawnz).CopyTo(header, 10);
BitConverter.GetBytes(level.spawny).CopyTo(header, 12); BitConverter.GetBytes(lvl.spawny).CopyTo(header, 12);
header[14] = level.rotx; header[14] = lvl.rotx;
header[15] = level.roty; header[15] = lvl.roty;
header[16] = (byte)level.permissionvisit; header[16] = (byte)lvl.permissionvisit;
header[17] = (byte)level.permissionbuild; header[17] = (byte)lvl.permissionbuild;
gs.Write(header, 0, header.Length); gs.Write(header, 0, header.Length);
}
byte[] blocks = level.blocks; static void WriteBlocksSection(Level lvl, Stream gs) {
byte[] blocks = lvl.blocks;
int start = 0, len = 0; int start = 0, len = 0;
for (int i = 0; i < blocks.Length; ++i) { for (int i = 0; i < blocks.Length; ++i) {
byte block = blocks[i], convBlock = 0; byte block = blocks[i], convBlock = 0;
@ -57,15 +64,16 @@ namespace MCGalaxy.Levels.IO {
} }
} }
if (len > 0) gs.Write(blocks, start, len); if (len > 0) gs.Write(blocks, start, len);
}
// write out new blockdefinitions data static void WriteBlockDefsSection(Level lvl, Stream gs) {
gs.WriteByte(0xBD); gs.WriteByte(0xBD);
int index = 0; int index = 0;
for (int y = 0; y < level.ChunksY; y++) for (int y = 0; y < lvl.ChunksY; y++)
for (int z = 0; z < level.ChunksZ; z++) for (int z = 0; z < lvl.ChunksZ; z++)
for (int x = 0; x < level.ChunksX; x++) for (int x = 0; x < lvl.ChunksX; x++)
{ {
byte[] chunk = level.CustomBlocks[index]; byte[] chunk = lvl.CustomBlocks[index];
if (chunk == null) { if (chunk == null) {
gs.WriteByte(0); gs.WriteByte(0);
} else { } else {
@ -75,74 +83,70 @@ namespace MCGalaxy.Levels.IO {
index++; index++;
} }
} }
public static void LoadDimensions(string file, out ushort width, out ushort height, out ushort length) {
using (Stream fs = File.OpenRead(file), gs = new GZipStream(fs, CompressionMode.Decompress, true)) {
byte[] header = new byte[16];
int offset = 0;
Vec3U16 dims = ReadHeader(gs, header, out offset);
width = dims.X; height = dims.Y; length = dims.Z;
}
} }
public static Level Load(string name, string file) { public static Level Load(string name, string file) {
using (Stream fs = File.OpenRead(file), gs = new GZipStream(fs, CompressionMode.Decompress, true)) using (Stream fs = File.OpenRead(file), gs = new GZipStream(fs, CompressionMode.Decompress, true)) {
{
byte[] header = new byte[16]; byte[] header = new byte[16];
gs.Read(header, 0, 2);
ushort[] vars = new ushort[6];
vars[0] = BitConverter.ToUInt16(header, 0);
int offset = 0; int offset = 0;
if (vars[0] == 1874) { // version field, width is next ushort Vec3U16 dims = ReadHeader(gs, header, out offset);
Level lvl = new Level(name, dims.X, dims.Y, dims.Z);
lvl.spawnx = BitConverter.ToUInt16(header, offset + 4);
lvl.spawnz = BitConverter.ToUInt16(header, offset + 6);
lvl.spawny = BitConverter.ToUInt16(header, offset + 8);
lvl.rotx = header[offset + 10];
lvl.roty = header[offset + 11];
gs.Read(lvl.blocks, 0, lvl.blocks.Length);
ReadBlockDefsSection(lvl, gs);
return lvl;
}
}
static Vec3U16 ReadHeader(Stream gs, byte[] header, out int offset) {
gs.Read(header, 0, 2);
Vec3U16 dims = default(Vec3U16);
dims.X = BitConverter.ToUInt16(header, 0);
if (dims.X == 1874) { // version field, width is next ushort
gs.Read(header, 0, 16); gs.Read(header, 0, 16);
vars[0] = BitConverter.ToUInt16(header, 0); dims.X = BitConverter.ToUInt16(header, 0);
offset = 2; offset = 2;
} else { } else {
gs.Read(header, 0, 12); gs.Read(header, 0, 12);
offset = 0;
} }
vars[1] = BitConverter.ToUInt16(header, offset);
vars[2] = BitConverter.ToUInt16(header, offset + 2);
Level level = new Level(name, vars[0], vars[2], vars[1]); dims.Z = BitConverter.ToUInt16(header, offset);
level.spawnx = BitConverter.ToUInt16(header, offset + 4); dims.Y = BitConverter.ToUInt16(header, offset + 2);
level.spawnz = BitConverter.ToUInt16(header, offset + 6); return dims;
level.spawny = BitConverter.ToUInt16(header, offset + 8); }
level.rotx = header[offset + 10];
level.roty = header[offset + 11];
gs.Read(level.blocks, 0, level.blocks.Length); static void ReadBlockDefsSection(Level lvl, Stream gs) {
if (gs.ReadByte() != 0xBD) if (gs.ReadByte() != 0xBD) return;
return level;
int index = 0; int index = 0;
for (int y = 0; y < level.ChunksY; y++) for (int y = 0; y < lvl.ChunksY; y++)
for (int z = 0; z < level.ChunksZ; z++) for (int z = 0; z < lvl.ChunksZ; z++)
for (int x = 0; x < level.ChunksX; x++) for (int x = 0; x < lvl.ChunksX; x++)
{ {
if (gs.ReadByte() == 1) { if (gs.ReadByte() == 1) {
byte[] chunk = new byte[16 * 16 * 16]; byte[] chunk = new byte[16 * 16 * 16];
gs.Read(chunk, 0, chunk.Length); gs.Read(chunk, 0, chunk.Length);
level.CustomBlocks[index] = chunk; lvl.CustomBlocks[index] = chunk;
} }
index++; index++;
} }
return level;
}
}
public static void LoadDimensions(string file, out ushort width, out ushort height, out ushort length) {
using (Stream fs = File.OpenRead(file), gs = new GZipStream(fs, CompressionMode.Decompress, true))
{
byte[] header = new byte[16];
gs.Read(header, 0, 2);
ushort[] vars = new ushort[6];
vars[0] = BitConverter.ToUInt16(header, 0);
int offset = 0;
if (vars[0] == 1874) { // version field, width is next ushort
gs.Read(header, 0, 16);
vars[0] = BitConverter.ToUInt16(header, 0);
offset = 2;
} else {
gs.Read(header, 0, 12);
}
vars[1] = BitConverter.ToUInt16(header, offset);
vars[2] = BitConverter.ToUInt16(header, offset + 2);
width = vars[0]; height = vars[2]; length = vars[1];
}
} }
} }
} }