private void SaveWorld(MapFile map, List <SerialisedObject> list) { // call the avengers var id = 1; var idMap = map.Worldspawn.FindAll().ToDictionary(x => x, x => id++); // Get the world, groups, and non-entity solids var vmfWorld = new VmfWorld(map.Worldspawn); var worldObj = vmfWorld.ToSerialisedObject(); SerialiseWorldspawnChildren(map.Worldspawn, worldObj, idMap, 0, map.Worldspawn.Children); list.Add(worldObj); // Entities are separate from the world var entities = map.Worldspawn.FindAll().OfType <Entity>().Where(x => x != map.Worldspawn).Select(x => SerialiseEntity(x, idMap)).ToList(); list.AddRange(entities); }
void LoadWorld(MapFile map, List <SerialisedObject> objects) { List <VmfObject> vos = objects.Select(VmfObject.Deserialise).Where(vo => vo != null).ToList(); VmfWorld world = vos.OfType <VmfWorld>().FirstOrDefault() ?? new VmfWorld(new SerialisedObject("world")); // A map of loaded object -> vmf id Dictionary <MapObject, int> mapToSource = new Dictionary <MapObject, int>(); world.Editor.Apply(map.Worldspawn); mapToSource.Add(map.Worldspawn, world.ID); map.Worldspawn.ClassName = world.ClassName; map.Worldspawn.SpawnFlags = world.SpawnFlags; foreach (KeyValuePair <string, string> wp in world.Properties) { map.Worldspawn.Properties[wp.Key] = wp.Value; } List <VmfObject> tree = new List <VmfObject>(); foreach (VmfObject vo in vos) { if (vo.Editor.ParentID == 0) { vo.Editor.ParentID = world.ID; } // Flatten the tree (nested hiddens -> no more hiddens) // (Flat tree includes self as well) List <VmfObject> flat = vo.Flatten().ToList(); // Set the default parent id for all the child objects foreach (VmfObject child in flat) { if (child.Editor.ParentID == 0) { child.Editor.ParentID = vo.ID; } } // Add the objects to the tree tree.AddRange(flat); } world.Editor.ParentID = 0; tree.Remove(world); // All objects should have proper ids by now, get rid of anything with parentid 0 just in case Dictionary <int, List <VmfObject> > grouped = tree.GroupBy(x => x.Editor.ParentID).ToDictionary(x => x.Key, x => x.ToList()); // Step through each level of the tree and add them to their parent branches List <MapObject> leaves = new List <MapObject> { map.Worldspawn }; // Use a iteration limit of 1000. If the tree's that deep, I don't want to load your map anyway... for (int i = 0; i < 1000 && leaves.Any(); i++) // i.e. while (leaves.Any()) { List <MapObject> newLeaves = new List <MapObject>(); foreach (MapObject leaf in leaves) { int sourceId = mapToSource[leaf]; if (!grouped.ContainsKey(sourceId)) { continue; } List <VmfObject> items = grouped[sourceId]; // Create objects from items foreach (VmfObject item in items) { MapObject mapObject = item.ToMapObject(); mapToSource.Add(mapObject, item.ID); leaf.Children.Add(mapObject); newLeaves.Add(mapObject); } } leaves = newLeaves; } // Now we should have a nice neat hierarchy of objects }