示例#1
0
        private void Parse(List <string> rawBlock)
        {
            int i = 0;

            while (i < rawBlock.Count)
            {
                string item = rawBlock[i];

                if (item.Contains(KeyValDelimiter))
                {
                    List <KeyValuePair <string, string> > rawKeyVals = ExtractKeyVals(item);

                    string classname = rawKeyVals.Find(s => s.Key == "classname").Value;

                    foreach (KeyValuePair <string, string> rawKeyVal in rawKeyVals)
                    {
                        Option newOption;
                        if (Definitions.ContainsKey(classname) && Definitions[classname].KeyValsTemplate.ContainsKey(rawKeyVal.Key))
                        {
                            newOption = new Option(Definitions[classname].KeyValsTemplate[rawKeyVal.Key]);
                        }
                        else
                        {
                            newOption = new Option();
                        }
                        newOption.Value = rawKeyVal.Value;

                        if (!KeyVals.ContainsKey(rawKeyVal.Key))
                        {
                            KeyVals.Add(rawKeyVal.Key, newOption);
                        }
                        else
                        {
                            KeyVals[rawKeyVal.Key] = newOption;
                        }
                    }

                    ++i;
                }
                // An open delimiter that's the first item in the raw block is just the
                // start of the top level block; any others indicate children.
                else if (item == OpenDelimiter && i != 0)
                {
                    int childOpenBraceIndex = i + 1;

                    var childBlock = new QuakeBlock(rawBlock, childOpenBraceIndex, Definitions);
                    Children.Add(childBlock);

                    i = childBlock.RawStartIndex + childBlock.RawLength;
                }
                else if (item.StartsWith("(", StringComparison.OrdinalIgnoreCase))
                {
                    string solid = item;
                    int    j     = i + 1;
                    while (rawBlock[j] != CloseDelimiter)
                    {
                        solid += rawBlock[j];
                        j++;
                    }

                    Solids.Add(new Solid(ExtractSides(solid)));

                    i += j;
                }
                else
                {
                    i++;
                }
            }
        }
示例#2
0
        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);
            }
        }