private void OpenMap(string fileName) { if (String.IsNullOrEmpty(fileName)) { return; } string ext = Path.GetExtension(fileName); if (ext.ToLower() != ".map") { throw new InvalidDataException("Unrecognized map format!"); } var definitions = new Dictionary <string, DefinitionDictionary>(); foreach (string path in Settings.Local.DefinitionDictionaryPaths) { definitions.Add(path, Loader.LoadDefinitionDictionary(path)); } using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { Map = new QuakeMap(stream, definitions.Values.ToList().Stack()); } Map.ProgressUpdated += ProgressReported; Task.Run(() => { Map.Parse(); Settings.Updatables.Add(Map); Settings.Save(); BackEnd.InitTextures(Map.Textures); GetAllThisNonsenseReady(); Application.Instance.Invoke(() => { MapReloader.File = fileName; MapReloader.Enabled = cbxAutoReload.Checked; }); }); }
protected override void ExtractRenderables(Block block) { var b = block as QuakeBlock; // Contains brushes. Checking the Solids count allows for both known // and unknown solid entities, which can be treated the same way. if (b.Solids.Count > 0) { foreach (Solid solid in b.Solids) { Renderables.Add(new QuakeBrush(solid)); } } // Known point entity. else if (Definition?.ClassType == ClassType.Point) { if (KeyVals.ContainsKey("origin")) { Position = KeyVals["origin"].Value.ToVector3(); } if (Definition.RenderableSources.ContainsKey(RenderableSource.Key)) { string key = Definition.RenderableSources[RenderableSource.Key]; string path = KeyVals[key].Value; if (path.EndsWith(".map", StringComparison.OrdinalIgnoreCase)) { string oldCwd = Directory.GetCurrentDirectory(); string instancePath; if (Path.IsPathRooted(path)) { instancePath = path; } else { instancePath = Path.Combine(oldCwd, path); } QuakeMap map; using (FileStream stream = File.OpenRead(instancePath)) { map = new QuakeMap(stream, Definition.DefinitionCollection); } map.Parse(); if (Definition.ClassName == "misc_external_map") { map.Prune(ClassType.Point); } // For now just tweak the instance map's renderable // geometry; name fixup and variable replacement will // be easier to accomplish as a separate pass, once all // instance maps have been loaded and parsed. map.Transform(this); UserData = map; foreach (MapObject mo in map.AllObjects) { var modified = new QuakeMapObject(mo); if (mo.KeyVals["classname"].Value == "worldspawn") { modified.Saveability = Saveability.Solids; } Children.Add(modified); } // Create a simple box to mark this instance's origin. Renderable box = new BoxGenerator(Color4.Orange).Generate(); box.Position = Position; box.Transformability = Definition.RenderableTransformability; Renderables.Add(box); } } else if (Definition.RenderableSources.ContainsKey(RenderableSource.Model)) { LoadModel(block as QuakeBlock); } else if (Definition.RenderableSources.ContainsKey(RenderableSource.Size)) { Aabb s = Definition.Size; Renderable box = new BoxGenerator(s.Min, s.Max, Definition.Color).Generate(); box.Position = Position; Renderables.Add(box); } // Known point entity with no predefined size. else { Renderable gem = new GemGenerator(Color4.Lime).Generate(); gem.Position = Position; gem.Transformability = Definition.RenderableTransformability; Renderables.Add(gem); } } // Unknown entity. else if (Definition == null) { Renderable gem = new GemGenerator().Generate(); gem.Position = Position; gem.Transformability = Definition.RenderableTransformability; Renderables.Add(gem); } }