ClassiCube/ClassicalSharp/Map/Formats/MapCw.Exporter.cs

136 lines
4.2 KiB
C#

using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
using OpenTK;
namespace ClassicalSharp {
public sealed partial class MapCw : IMapFileFormat {
public override bool SupportsSaving {
get { return true; }
}
BinaryWriter writer;
public override void Save( Stream stream, Game game ) {
using( GZipStream wrapper = new GZipStream( stream, CompressionMode.Compress ) ) {
writer = new BinaryWriter( wrapper );
this.game = game;
map = game.Map;
WriteTag( NbtTagType.Compound ); WriteString( "ClassicWorld" );
WriteTag( NbtTagType.Int8 );
WriteString( "FormatVersion" ); WriteInt8( 1 );
WriteTag( NbtTagType.Int8Array );
WriteString( "UUID" ); WriteInt32( 16 );
WriteBytes( map.Uuid.ToByteArray() );
WriteTag( NbtTagType.Int16 );
WriteString( "X" ); WriteInt16( (short)map.Width );
WriteTag( NbtTagType.Int16 );
WriteString( "Y" ); WriteInt16( (short)map.Height );
WriteTag( NbtTagType.Int16 );
WriteString( "Z" ); WriteInt16( (short)map.Length );
WriteSpawnCompoundTag();
WriteTag( NbtTagType.Int8Array );
WriteString( "BlockArray" ); WriteInt32( map.mapData.Length );
WriteBytes( map.mapData );
WriteMetadata();
WriteTag( NbtTagType.End );
}
}
void WriteSpawnCompoundTag() {
WriteTag( NbtTagType.Compound ); WriteString( "Spawn" );
Vector3 spawn = game.LocalPlayer.SpawnPoint;
WriteTag( NbtTagType.Int16 );
WriteString( "X" ); WriteInt16( (short)(spawn.X * 32) );
WriteTag( NbtTagType.Int16 );
WriteString( "Y" ); WriteInt16( (short)(spawn.Y * 32) );
WriteTag( NbtTagType.Int16 );
WriteString( "Z" ); WriteInt16( (short)(spawn.Z * 32) );
WriteTag( NbtTagType.Int8 );
WriteString( "H" ); WriteInt8( 0 );
WriteTag( NbtTagType.Int8 );
WriteString( "P" ); WriteInt8( 0 );
WriteTag( NbtTagType.End );
}
void WriteMetadata() {
WriteTag( NbtTagType.Compound ); WriteString( "Metadata" );
WriteTag( NbtTagType.Compound ); WriteString( "CPE" );
LocalPlayer p = game.LocalPlayer;
WriteCpeExtCompound( "ClickDistance", 1 );
WriteTag( NbtTagType.Int16 );
WriteString( "Distance" ); WriteInt16( (short)(p.ReachDistance * 32) );
WriteTag( NbtTagType.End );
WriteCpeExtCompound( "EnvWeatherType", 1 );
WriteTag( NbtTagType.Int8 );
WriteString( "WeatherType" ); WriteInt8( (sbyte)((byte)map.Weather) );
WriteTag( NbtTagType.End );
WriteCpeExtCompound( "EnvColors", 1 );
WriteColourCompound( "Sky", map.SkyCol );
WriteColourCompound( "Cloud", map.CloudsCol );
WriteColourCompound( "Fog", map.FogCol );
WriteColourCompound( "Ambient", map.Shadowlight );
WriteColourCompound( "Sunlight", map.Sunlight );
WriteTag( NbtTagType.End );
WriteTag( NbtTagType.End );
WriteTag( NbtTagType.End );
}
void WriteCpeExtCompound( string name, int version ) {
WriteTag( NbtTagType.Compound ); WriteString( name );
WriteTag( NbtTagType.Int32 );
WriteString( "ExtensionVersion" ); WriteInt32( 1 );
}
void WriteColourCompound( string name, FastColour col ) {
WriteTag( NbtTagType.Compound ); WriteString( name );
WriteTag( NbtTagType.Int16 );
WriteString( "R" ); WriteInt16( col.R );
WriteTag( NbtTagType.Int16 );
WriteString( "G" ); WriteInt16( col.G );
WriteTag( NbtTagType.Int16 );
WriteString( "B" ); WriteInt16( col.B );
WriteTag( NbtTagType.End );
}
void WriteTag( NbtTagType v ) { writer.Write( (byte)v ); }
void WriteInt64( long v ) { writer.Write( IPAddress.HostToNetworkOrder( v ) ); }
void WriteInt32( int v ) { writer.Write( IPAddress.HostToNetworkOrder( v ) ); }
void WriteInt16( short v ) { writer.Write( IPAddress.HostToNetworkOrder( v ) ); }
void WriteInt8( sbyte v ) { writer.Write( (byte)v ); }
void WriteBytes( byte[] v ) { writer.Write( v ); }
void WriteString( string value ) {
ushort len = (ushort)value.Length;
byte[] data = Encoding.UTF8.GetBytes( value );
WriteInt16( (short)len );
writer.Write( data );
}
}
}