private DetailObject CreateDetailInstance( Dictionary <DetailTemplate, DetailObject> mapping, Dictionary <BehaviourTemplate, Behaviour> behaviours, DetailTemplate template, DetailObject parent) { Vector3 pos = Vector3.Zero; if (template.Position != null) { pos = template.GetPosition(); } Shape shape = null; if (template.Shape != null) { shape = DetailHelper.CreateShape(template.Shape.GetSize()); } DetailObject root = this.CreateDetail(template.Model, pos, parent, shape); if (template.Rotation != null) { root.Rotation = template.GetRotation(); } if (template.Children != null) { foreach (var child in template.Children) { CreateDetailInstance(mapping, behaviours, child, root); } } mapping.Add(template, root); if (template.Behaviours != null) { foreach (var behav in template.Behaviours) { var type = Type.GetType(behav.Class); if (type.IsSubclassOf(typeof(Behaviour)) == false) { throw new InvalidOperationException("Invalid behaviour type: " + behav.Class); } Behaviour behaviour = root.CreateBehaviour(type, true); behaviours.Add(behav, behaviour); } } return(root); }
public void Load(Stream fs, bool leaveOpen) { // Reset whole world foreach (var block in blocks.ToArray()) { this[block.X, block.Y, block.Z] = null; } Action <bool> assert = (b) => { if (!b) { throw new InvalidDataException(); } }; using (var br = new BinaryReader(fs, Encoding.UTF8, leaveOpen)) { assert(br.ReadString() == "BLOCKWORLD"); int major = br.ReadByte(); int minor = br.ReadByte(); assert(major == 1); int typeCount = br.ReadInt32(); Type[] types = new Type[typeCount]; for (int i = 0; i < typeCount; i++) { string typeName = br.ReadString(); types[i] = Type.GetType(typeName); if (types[i] == null) { throw new TypeLoadException("Could not find type " + typeName); } } long blockCount = br.ReadInt64(); for (long i = 0; i < blockCount; i++) { int x = br.ReadInt32(); int y = br.ReadInt32(); int z = br.ReadInt32(); Type type = types[br.ReadInt32()]; var block = Activator.CreateInstance(type) as Block; block.Deserialize(br); this[x, y, z] = block; } // Details are stored here as well if (minor == 1) { int detailCount = br.ReadInt32(); for (int i = 0; i < detailCount; i++) { int id = br.ReadInt32(); string model = br.ReadString(); int parentID = br.ReadInt32(); var position = br.ReadVector3(); var rotation = br.ReadQuaternion(); Shape shape = null; bool hasShape = br.ReadBoolean(); if (hasShape) { var size = br.ReadVector3(); shape = new BoxShape(size.Jitter()); } DetailObject detail = new DetailObject(this.GetDetail(parentID), id, shape); if (string.IsNullOrWhiteSpace(model) == false) { detail.Model = model; } detail.Position = position; detail.Rotation = rotation; this.RegisterDetail(detail); int behaviourCount = br.ReadInt32(); for (int j = 0; j < behaviourCount; j++) { var typeName = br.ReadString(); var type = Type.GetType(typeName, true); int behaviourID = br.ReadInt32(); bool isEnabled = br.ReadBoolean(); var behaviour = (Behaviour)Activator.CreateInstance(type); detail.CreateBehaviour(behaviour, behaviourID, isEnabled); } } int signalCount = br.ReadInt32(); for (int j = 0; j < signalCount; j++) { var signalDetailID = br.ReadInt32(); var signalBehaviourID = br.ReadInt32(); var signalName = br.ReadString(); var signal = this.GetDetail(signalDetailID).Behaviours[signalBehaviourID].Signals[signalName]; var slotCount = br.ReadInt32(); for (int k = 0; k < slotCount; k++) { var slotDetailID = br.ReadInt32(); var slotBehaviourID = br.ReadInt32(); var slotName = br.ReadString(); var slot = this.GetDetail(slotDetailID).Behaviours[slotBehaviourID].Slots[slotName]; signal.Connect(slot); } } } } }