public void Save(string fileName, WorldSaveMode mode) { using (var fs = File.Open(fileName, FileMode.Create, FileAccess.Write)) { this.Save(fs, mode); } }
public void Save(Stream fs, WorldSaveMode mode, bool leaveOpen) { if (mode.HasFlag(WorldSaveMode.SignalConnections) && !mode.HasFlag(WorldSaveMode.Details)) throw new ArgumentException("WorldSaveMode.SignalConnections requires WorldSaveMode.Details to be set as well."); var blocks = this.blocks.Where(x => (x.Value != null) && (x.Value.Block != null)).ToArray(); using (var bw = new BinaryWriter(fs, Encoding.UTF8, leaveOpen)) { bw.Write("BLOCKWORLD"); bw.Write((byte)1); bw.Write((byte)1); if (mode.HasFlag(WorldSaveMode.Blocks)) { var types = blocks.Select(x => x.Value.Block.GetType()).Distinct().ToList(); bw.Write(types.Count); for (int i = 0; i < types.Count; i++) { bw.Write(types[i].AssemblyQualifiedName); } bw.Write(blocks.LongLength); foreach (var data in blocks) { var block = data.Value.Block; bw.Write(data.X); bw.Write(data.Y); bw.Write(data.Z); bw.Write(types.IndexOf(block.GetType())); block.Serialize(bw); } } else { bw.Write((int)0); bw.Write((long)0); } if (mode.HasFlag(WorldSaveMode.Details)) { // Sort by ID: Parent.ID must always be smaller than childs ID, // so we create the parents before their children var details = this.details.OrderBy(d => d.ID).ToArray(); bw.Write(details.Length); for (int i = 0; i < details.Length; i++) { var detail = details[i]; bw.Write(detail.ID); bw.Write(detail.Model ?? ""); if (detail.Parent != null) bw.Write(detail.Parent.ID); else bw.Write((Int32)(-1)); bw.Write(detail.Position); bw.Write(detail.Rotation); bool hasShape = (detail.Shape != null); bw.Write(hasShape); if (hasShape) { var shape = (BoxShape)detail.Shape; bw.Write(shape.Size.TK()); } var behaviours = detail.Behaviours.Values.ToArray(); bw.Write(behaviours.Length); for (int j = 0; j < behaviours.Length; j++) { var behaviour = behaviours[j]; string type = behaviour.GetType().AssemblyQualifiedName; bw.Write(type); bw.Write(behaviour.ID); bw.Write(behaviour.IsEnabled); } } if (mode.HasFlag(WorldSaveMode.Details)) { var signals = details .SelectMany(d => d.Behaviours.Values) .SelectMany(b => b.Signals.Values) .Where(s => (s.Slots.Count() > 0)) .ToArray(); bw.Write(signals.Length); for (int j = 0; j < signals.Length; j++) { var signal = signals[j]; bw.Write(signal.Behaviour.Detail.ID); bw.Write(signal.Behaviour.ID); bw.Write(signal.Name); var slots = signal.Slots.ToArray(); bw.Write(slots.Length); for (int k = 0; k < slots.Length; k++) { var slot = slots[k]; bw.Write(slot.Behaviour.Detail.ID); bw.Write(slot.Behaviour.ID); bw.Write(slot.Name); } } } else { bw.Write((int)0); // 0 signal connections } } else { bw.Write((int)0); // 0 details bw.Write((int)0); // 0 signal connections } bw.Flush(); } }
public void Save(Stream fs, WorldSaveMode mode) { this.Save(fs, mode, false); }
public void Save(Stream fs, WorldSaveMode mode, bool leaveOpen) { if (mode.HasFlag(WorldSaveMode.SignalConnections) && !mode.HasFlag(WorldSaveMode.Details)) { throw new ArgumentException("WorldSaveMode.SignalConnections requires WorldSaveMode.Details to be set as well."); } var blocks = this.blocks.Where(x => (x.Value != null) && (x.Value.Block != null)).ToArray(); using (var bw = new BinaryWriter(fs, Encoding.UTF8, leaveOpen)) { bw.Write("BLOCKWORLD"); bw.Write((byte)1); bw.Write((byte)1); if (mode.HasFlag(WorldSaveMode.Blocks)) { var types = blocks.Select(x => x.Value.Block.GetType()).Distinct().ToList(); bw.Write(types.Count); for (int i = 0; i < types.Count; i++) { bw.Write(types[i].AssemblyQualifiedName); } bw.Write(blocks.LongLength); foreach (var data in blocks) { var block = data.Value.Block; bw.Write(data.X); bw.Write(data.Y); bw.Write(data.Z); bw.Write(types.IndexOf(block.GetType())); block.Serialize(bw); } } else { bw.Write((int)0); bw.Write((long)0); } if (mode.HasFlag(WorldSaveMode.Details)) { // Sort by ID: Parent.ID must always be smaller than childs ID, // so we create the parents before their children var details = this.details.OrderBy(d => d.ID).ToArray(); bw.Write(details.Length); for (int i = 0; i < details.Length; i++) { var detail = details[i]; bw.Write(detail.ID); bw.Write(detail.Model ?? ""); if (detail.Parent != null) { bw.Write(detail.Parent.ID); } else { bw.Write((Int32)(-1)); } bw.Write(detail.Position); bw.Write(detail.Rotation); bool hasShape = (detail.Shape != null); bw.Write(hasShape); if (hasShape) { var shape = (BoxShape)detail.Shape; bw.Write(shape.Size.TK()); } var behaviours = detail.Behaviours.Values.ToArray(); bw.Write(behaviours.Length); for (int j = 0; j < behaviours.Length; j++) { var behaviour = behaviours[j]; string type = behaviour.GetType().AssemblyQualifiedName; bw.Write(type); bw.Write(behaviour.ID); bw.Write(behaviour.IsEnabled); } } if (mode.HasFlag(WorldSaveMode.Details)) { var signals = details .SelectMany(d => d.Behaviours.Values) .SelectMany(b => b.Signals.Values) .Where(s => (s.Slots.Count() > 0)) .ToArray(); bw.Write(signals.Length); for (int j = 0; j < signals.Length; j++) { var signal = signals[j]; bw.Write(signal.Behaviour.Detail.ID); bw.Write(signal.Behaviour.ID); bw.Write(signal.Name); var slots = signal.Slots.ToArray(); bw.Write(slots.Length); for (int k = 0; k < slots.Length; k++) { var slot = slots[k]; bw.Write(slot.Behaviour.Detail.ID); bw.Write(slot.Behaviour.ID); bw.Write(slot.Name); } } } else { bw.Write((int)0); // 0 signal connections } } else { bw.Write((int)0); // 0 details bw.Write((int)0); // 0 signal connections } bw.Flush(); } }