Exemplo n.º 1
0
        private void ParseAt(DataStructures.GameData.GameData gd, IEnumerator <LexObject> iterator)
        {
            iterator.MoveNext();
            var type = iterator.Current.Value;

            if (type.Equals("include", StringComparison.InvariantCultureIgnoreCase))
            {
                Expect(iterator, LexType.String);
                if (CurrentFile != null)
                {
                    var filename = iterator.Current.GetValue();
                    var path     = Path.GetDirectoryName(CurrentFile) ?? "";
                    var incfile  = Path.Combine(path, filename);

                    var current = CurrentFile;
                    var incgd   = GetGameDataFromFile(incfile);
                    CurrentFile = current;

                    if (!gd.Includes.Any(x => String.Equals(x, filename, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        gd.Includes.Add(filename);
                    }

                    // Merge the included gamedata into the current one
                    gd.MapSizeHigh = Math.Max(incgd.MapSizeHigh, gd.MapSizeHigh);
                    gd.MapSizeLow  = Math.Min(incgd.MapSizeLow, gd.MapSizeLow);
                    gd.Includes.AddRange(incgd.Includes.Where(x => !gd.Includes.Contains(x)));
                    gd.Classes.AddRange(incgd.Classes.Where(x => !gd.Classes.Any(y => String.Equals(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase))));
                    gd.AutoVisgroups.AddRange(incgd.AutoVisgroups.Where(x => !gd.AutoVisgroups.Any(y => String.Equals(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase))));
                    gd.MaterialExclusions.AddRange(incgd.MaterialExclusions.Where(x => !gd.MaterialExclusions.Any(y => String.Equals(x, y, StringComparison.InvariantCultureIgnoreCase))));
                }
                else
                {
                    throw new ProviderException("Unable to include a file when not reading from a file.");
                }
            }
            else if (type.Equals("mapsize", StringComparison.InvariantCultureIgnoreCase))
            {
                Expect(iterator, LexType.OpenParen);
                Expect(iterator, LexType.Value);
                gd.MapSizeLow = Int32.Parse(iterator.Current.Value);
                Expect(iterator, LexType.Comma);
                Expect(iterator, LexType.Value);
                gd.MapSizeHigh = Int32.Parse(iterator.Current.Value);
                Expect(iterator, LexType.CloseParen);
            }
            else if (type.Equals("materialexclusion", StringComparison.InvariantCultureIgnoreCase))
            {
                Expect(iterator, LexType.OpenBracket);
                iterator.MoveNext();
                while (iterator.Current.Type != LexType.CloseBracket)
                {
                    Assert(iterator.Current, iterator.Current.IsValueOrString(), "Expected value type, got " + iterator.Current.Type + ".");
                    var exclusion = iterator.Current.GetValue();
                    gd.MaterialExclusions.Add(exclusion);
                    iterator.MoveNext();
                }
            }
            else if (type.Equals("autovisgroup", StringComparison.InvariantCultureIgnoreCase))
            {
                Expect(iterator, LexType.Equals);

                iterator.MoveNext();
                Assert(iterator.Current, iterator.Current.IsValueOrString(), "Expected value type, got " + iterator.Current.Type + ".");
                var sectionName = iterator.Current.GetValue();
                var sect        = new AutoVisgroupSection {
                    Name = sectionName
                };

                Expect(iterator, LexType.OpenBracket);
                iterator.MoveNext();
                while (iterator.Current.Type != LexType.CloseBracket)
                {
                    Assert(iterator.Current, iterator.Current.IsValueOrString(), "Expected value type, got " + iterator.Current.Type + ".");
                    var groupName = iterator.Current.GetValue();
                    var grp       = new AutoVisgroup {
                        Name = groupName
                    };

                    Expect(iterator, LexType.OpenBracket);
                    iterator.MoveNext();
                    while (iterator.Current.Type != LexType.CloseBracket)
                    {
                        Assert(iterator.Current, iterator.Current.IsValueOrString(), "Expected value type, got " + iterator.Current.Type + ".");
                        var entity = iterator.Current.GetValue();
                        grp.EntityNames.Add(entity);
                        iterator.MoveNext();
                    }

                    sect.Groups.Add(grp);
                }

                gd.AutoVisgroups.Add(sect);
            }
            else
            {
                // Parsing:
                // @TypeClass name(param, param) name()
                var ct  = ParseClassType(type, iterator.Current);
                var gdo = new GameDataObject("", "", ct);
                iterator.MoveNext();
                while (iterator.Current.Type == LexType.Value)
                {
                    // Parsing:
                    // @TypeClass {name(param, param) name()}
                    var name = iterator.Current.Value;
                    var bh   = new Behaviour(name);
                    iterator.MoveNext();
                    if (iterator.Current.Type == LexType.Value)
                    {
                        // Allow for the following (first seen in hl2 base):
                        // @PointClass {halfgridsnap} base(Targetname)
                        continue;
                    }
                    Assert(iterator.Current, iterator.Current.Type == LexType.OpenParen, "Unexpected " + iterator.Current.Type);
                    iterator.MoveNext();
                    while (iterator.Current.Type != LexType.CloseParen)
                    {
                        // Parsing:
                        // name({param, param})
                        if (iterator.Current.Type != LexType.Comma)
                        {
                            Assert(iterator.Current, iterator.Current.Type == LexType.Value || iterator.Current.Type == LexType.String,
                                   "Unexpected " + iterator.Current.Type + ".");
                            var value = iterator.Current.Value;
                            if (iterator.Current.Type == LexType.String)
                            {
                                value = value.Trim('"');
                            }
                            bh.Values.Add(value);
                        }
                        iterator.MoveNext();
                    }
                    Assert(iterator.Current, iterator.Current.Type == LexType.CloseParen, "Unexpected " + iterator.Current.Type);
                    // Treat base behaviour as a special case
                    if (bh.Name == "base")
                    {
                        gdo.BaseClasses.AddRange(bh.Values);
                    }
                    else
                    {
                        gdo.Behaviours.Add(bh);
                    }
                    iterator.MoveNext();
                }
                // = class_name : "Descr" + "iption" [
                Assert(iterator.Current, iterator.Current.Type == LexType.Equals, "Expected equals, got " + iterator.Current.Type);
                Expect(iterator, LexType.Value);
                gdo.Name = iterator.Current.Value;
                iterator.MoveNext();
                if (iterator.Current.Type == LexType.Colon)
                {
                    // Parsing:
                    // : {"Descr" + "iption"} [
                    iterator.MoveNext();
                    gdo.Description = ParsePlusString(iterator);
                }
                Assert(iterator.Current, iterator.Current.Type == LexType.OpenBracket, "Unexpected " + iterator.Current.Type);

                // Parsing:
                // name(type) : "Desc" : "Default" : "Long Desc" = [ ... ]
                // input name(type) : "Description"
                // output name(type) : "Description"
                iterator.MoveNext();
                while (iterator.Current.Type != LexType.CloseBracket)
                {
                    Assert(iterator.Current, iterator.Current.Type == LexType.Value, "Unexpected " + iterator.Current.Type);
                    var pt = iterator.Current.Value;
                    if (pt == "input" || pt == "output") // IO
                    {
                        // input name(type) : "Description"
                        var io = new IO();
                        Expect(iterator, LexType.Value);
                        io.IOType = (IOType)Enum.Parse(typeof(IOType), pt, true);
                        io.Name   = iterator.Current.Value;
                        Expect(iterator, LexType.OpenParen);
                        Expect(iterator, LexType.Value);
                        io.VariableType = ParseVariableType(iterator.Current);
                        Expect(iterator, LexType.CloseParen);
                        iterator.MoveNext(); // if not colon, this will be the value of the next io/property, or close
                        if (iterator.Current.Type == LexType.Colon)
                        {
                            iterator.MoveNext();
                            io.Description = ParsePlusString(iterator);
                        }
                        gdo.InOuts.Add(io);
                    }
                    else // Property
                    {
                        Expect(iterator, LexType.OpenParen);
                        Expect(iterator, LexType.Value);
                        var vartype = ParseVariableType(iterator.Current);
                        Expect(iterator, LexType.CloseParen);
                        var prop = new Property(pt, vartype);
                        iterator.MoveNext();
                        // if not colon or equals, this will be the value of the next io/property, or close
                        if (iterator.Current.Type == LexType.Value)
                        {
                            // Check for additional flags on the property
                            // e.g.: name(type) readonly : "This is a read only value"
                            //       name(type) report   : "This value will show in the entity report"
                            switch (iterator.Current.Value)
                            {
                            case "readonly":
                                prop.ReadOnly = true;
                                iterator.MoveNext();
                                break;

                            case "report":
                                prop.ShowInEntityReport = true;
                                iterator.MoveNext();
                                break;
                            }
                        }
                        do // Using do/while(false) so I can break out - reduces nesting.
                        {
                            // Short description
                            if (iterator.Current.Type != LexType.Colon)
                            {
                                break;
                            }
                            iterator.MoveNext();
                            prop.ShortDescription = ParsePlusString(iterator);

                            // Default value
                            if (iterator.Current.Type != LexType.Colon)
                            {
                                break;
                            }
                            iterator.MoveNext();
                            if (iterator.Current.Type != LexType.Colon) // Allow for ': :' structure (no default)
                            {
                                if (iterator.Current.Type == LexType.String)
                                {
                                    prop.DefaultValue = iterator.Current.Value.Trim('"');
                                }
                                else
                                {
                                    Assert(iterator.Current, iterator.Current.Type == LexType.Value, "Unexpected " + iterator.Current.Type);
                                    prop.DefaultValue = iterator.Current.Value;
                                }
                                iterator.MoveNext();
                            }

                            // Long description
                            if (iterator.Current.Type != LexType.Colon)
                            {
                                break;
                            }
                            iterator.MoveNext();
                            prop.Description = ParsePlusString(iterator);
                        } while (false);
                        if (iterator.Current.Type == LexType.Equals)
                        {
                            Expect(iterator, LexType.OpenBracket);
                            // Parsing property options:
                            // value : description
                            // value : description : 0
                            iterator.MoveNext();
                            while (iterator.Current.IsValueOrString())
                            {
                                var opt = new Option
                                {
                                    Key = iterator.Current.GetValue()
                                };
                                Expect(iterator, LexType.Colon);

                                // Some FGDs use values for property descriptions instead of strings
                                iterator.MoveNext();
                                Assert(iterator.Current, iterator.Current.IsValueOrString(), "Choices value must be value or string type.");
                                if (iterator.Current.Type == LexType.String)
                                {
                                    opt.Description = ParsePlusString(iterator);
                                }
                                else
                                {
                                    opt.Description = iterator.Current.GetValue();
                                    iterator.MoveNext();
                                    // ParsePlusString moves next once it's complete, need to do the same here
                                }

                                prop.Options.Add(opt);
                                if (iterator.Current.Type != LexType.Colon)
                                {
                                    continue;
                                }
                                Expect(iterator, LexType.Value);
                                opt.On = iterator.Current.Value == "1";
                                iterator.MoveNext();
                            }
                            Assert(iterator.Current, iterator.Current.Type == LexType.CloseBracket, "Unexpected " + iterator.Current.Type);
                            iterator.MoveNext();
                        }
                        gdo.Properties.Add(prop);
                    }
                }
                Assert(iterator.Current, iterator.Current.Type == LexType.CloseBracket, "Unexpected " + iterator.Current.Type);
                gd.Classes.Add(gdo);
            }
        }
Exemplo n.º 2
0
Arquivo: Map.cs Projeto: silky/sledge
        /// <summary>
        /// Should be called when a map is loaded. Sets up visgroups, object ids, gamedata, and textures.
        /// </summary>
        public void PostLoadProcess(GameData.GameData gameData, Func<string, ITexture> textureAccessor, Func<string, float> textureOpacity)
        {
            PartialPostLoadProcess(gameData, textureAccessor, textureOpacity);

            var all = WorldSpawn.FindAll();

            // Set maximum ids
            var maxObjectId = all.Max(x => x.ID);
            var faces = all.OfType<Solid>().SelectMany(x => x.Faces).ToList();
            var maxFaceId = faces.Any() ? faces.Max(x => x.ID) : 0;
            IDGenerator.Reset(maxObjectId, maxFaceId);

            // todo visgroups
            // WorldSpawn.ForEach(x => x.IsVisgroupHidden, x => x.IsVisgroupHidden = true, true);

            // Auto visgroup
            var auto = AutoVisgroup.GetDefaultAutoVisgroup();
            var quickHide = new AutoVisgroup {ID = int.MinValue, IsHidden = true, Name = "Autohide", Parent = auto, Visible = false};
            auto.Children.Add(quickHide);
            Visgroups.Add(auto);
            UpdateAutoVisgroups(all, false);

            // Purge empty groups
            foreach (var emptyGroup in WorldSpawn.Find(x => x is Group && !x.HasChildren))
            {
                emptyGroup.SetParent(null);
            }
        }