// This adds vertices
        private void WriteVertices(ICollection <Vertex> vertices, UniversalParser textmap)
        {
            // Go for all vertices
            foreach (Vertex v in vertices)
            {
                // Make collection
                UniversalCollection coll = new UniversalCollection();
                coll.Add("x", v.Position.x);
                coll.Add("y", v.Position.y);
                if (!float.IsNaN(v.ZCeiling))
                {
                    coll.Add("zceiling", v.ZCeiling);                                          //mxd
                }
                if (!float.IsNaN(v.ZFloor))
                {
                    coll.Add("zfloor", v.ZFloor);                                        //mxd
                }
                coll.Comment = v.Index.ToString();

                // Add custom fields
                AddCustomFields(v, "vertex", coll);

                // Store
                textmap.Root.Add("vertex", coll);
            }
        }
示例#2
0
        // ano - this returns all the unidentified data for preservation
        private void ReadUnidentifiedEntries(MapSet map, UniversalParser textmap)
        {
            UniversalCollection root         = textmap.Root;
            UniversalCollection unidentified = new UniversalCollection();

            foreach (UniversalEntry e in root)
            {
                switch (e.Key)
                {
                case "namespace":
                case "vertex":
                case "thing":
                case "linedef":
                case "sector":
                case "sidedef":
                    break;

                default:
                    unidentified.Add(e);
                    break;
                } // switch
            }     // foreach

            map.UnidentifiedUDMF = unidentified;
        } // ReadUnidentifiedEntries
        // This adds sectors
        private void WriteSectors(ICollection <Sector> sectors, UniversalParser textmap)
        {
            // Go for all sectors
            foreach (Sector s in sectors)
            {
                // Make collection
                UniversalCollection coll = new UniversalCollection();
                coll.Add("heightfloor", s.FloorHeight);
                coll.Add("heightceiling", s.CeilHeight);
                coll.Add("texturefloor", s.FloorTexture);
                coll.Add("textureceiling", s.CeilTexture);
                coll.Add("lightlevel", s.Brightness);
                if (s.Effect != 0)
                {
                    coll.Add("special", s.Effect);
                }
                if (s.Tag != 0)
                {
                    coll.Add("id", s.Tag);
                }
                coll.Comment = s.Index.ToString();

                // Add custom fields
                AddCustomFields(s, "sector", coll);

                // Store
                textmap.Root.Add("sector", coll);
            }
        }
        // This adds vertices
        private void WriteVertices(ICollection <Vertex> vertices, UniversalParser textmap)
        {
            // Go for all vertices
            foreach (Vertex v in vertices)
            {
                // Make collection
                UniversalCollection coll = new UniversalCollection();
                coll.Add("x", v.Position.x);
                coll.Add("y", v.Position.y);
                coll.Comment = v.Index.ToString();

                // Add custom fields
                AddCustomFields(v, "vertex", coll);

                // Store
                textmap.Root.Add("vertex", coll);
            }
        }
        // This adds sidedefs
        private void WriteSidedefs(ICollection <Sidedef> sidedefs, UniversalParser textmap, IDictionary <Sector, int> sectorids)
        {
            // Go for all sidedefs
            foreach (Sidedef s in sidedefs)
            {
                // Make collection
                UniversalCollection coll = new UniversalCollection();
                if (s.OffsetX != 0)
                {
                    coll.Add("offsetx", s.OffsetX);
                }
                if (s.OffsetY != 0)
                {
                    coll.Add("offsety", s.OffsetY);
                }
                if (s.LongHighTexture != MapSet.EmptyLongName)
                {
                    coll.Add("texturetop", s.HighTexture);
                }
                if (s.LongLowTexture != MapSet.EmptyLongName)
                {
                    coll.Add("texturebottom", s.LowTexture);
                }
                if (s.LongMiddleTexture != MapSet.EmptyLongName)
                {
                    coll.Add("texturemiddle", s.MiddleTexture);
                }
                coll.Add("sector", sectorids[s.Sector]);
                coll.Comment = s.Index.ToString();

                //mxd. Flags
                foreach (KeyValuePair <string, bool> flag in s.Flags)
                {
                    if (flag.Value)
                    {
                        coll.Add(flag.Key, flag.Value);
                    }
                }

                // Add custom fields
                AddCustomFields(s, "sidedef", coll);

                // Store
                textmap.Root.Add("sidedef", coll);
            }
        }
        // This adds custom fields from a map element to a collection
        private void AddCustomFields(MapElement element, string elementname, UniversalCollection collection)
        {
            // Add custom fields
            foreach (KeyValuePair <string, UniValue> f in element.Fields)
            {
                // Not a managed field?
                if (!config.SettingExists("managedfields." + elementname + "." + f.Key))
                {
                    // Add type information to DBS file for map
                    if (remembercustomtypes)
                    {
                        General.Map.Options.SetUniversalFieldType(elementname, f.Key, f.Value.Type);
                    }

                    // Store field
                    collection.Add(f.Key, f.Value.Value);
                }
            }
        }
        // This adds things
        private void WriteThings(ICollection <Thing> things, UniversalParser textmap)
        {
            // Go for all things
            foreach (Thing t in things)
            {
                // Make collection
                UniversalCollection coll = new UniversalCollection();
                if (t.Tag != 0)
                {
                    coll.Add("id", t.Tag);
                }
                coll.Add("x", t.Position.x);
                coll.Add("y", t.Position.y);
                if (t.Position.z != 0.0f)
                {
                    coll.Add("height", (float)t.Position.z);
                }
                coll.Add("angle", t.AngleDoom);
                coll.Add("type", t.Type);
                if (t.Action != 0)
                {
                    coll.Add("special", t.Action);
                }
                if (t.Args[0] != 0)
                {
                    coll.Add("arg0", t.Args[0]);
                }
                if (t.Args[1] != 0)
                {
                    coll.Add("arg1", t.Args[1]);
                }
                if (t.Args[2] != 0)
                {
                    coll.Add("arg2", t.Args[2]);
                }
                if (t.Args[3] != 0)
                {
                    coll.Add("arg3", t.Args[3]);
                }
                if (t.Args[4] != 0)
                {
                    coll.Add("arg4", t.Args[4]);
                }
                coll.Comment = t.Index.ToString();

                // Flags
                foreach (KeyValuePair <string, bool> flag in t.Flags)
                {
                    if (flag.Value)
                    {
                        coll.Add(flag.Key, flag.Value);
                    }
                }

                // Add custom fields
                AddCustomFields(t, "thing", coll);

                // Store
                textmap.Root.Add("thing", coll);
            }
        }
        // This adds linedefs
        private void WriteLinedefs(ICollection <Linedef> linedefs, UniversalParser textmap, IDictionary <Sidedef, int> sidedefids, IDictionary <Vertex, int> vertexids)
        {
            // Go for all linedefs
            foreach (Linedef l in linedefs)
            {
                // Make collection
                UniversalCollection coll = new UniversalCollection();
                if (l.Tag != 0)
                {
                    coll.Add("id", l.Tag);
                }
                coll.Add("v1", vertexids[l.Start]);
                coll.Add("v2", vertexids[l.End]);
                coll.Comment = l.Index.ToString();

                // Sidedef references
                if ((l.Front != null) && sidedefids.ContainsKey(l.Front))
                {
                    coll.Add("sidefront", sidedefids[l.Front]);
                }
                else
                {
                    coll.Add("sidefront", -1);
                }

                if ((l.Back != null) && sidedefids.ContainsKey(l.Back))
                {
                    coll.Add("sideback", sidedefids[l.Back]);
                }
                else
                {
                    coll.Add("sideback", -1);
                }

                // Special
                if (l.Action != 0)
                {
                    coll.Add("special", l.Action);
                }
                if (l.Args[0] != 0)
                {
                    coll.Add("arg0", l.Args[0]);
                }
                if (l.Args[1] != 0)
                {
                    coll.Add("arg1", l.Args[1]);
                }
                if (l.Args[2] != 0)
                {
                    coll.Add("arg2", l.Args[2]);
                }
                if (l.Args[3] != 0)
                {
                    coll.Add("arg3", l.Args[3]);
                }
                if (l.Args[4] != 0)
                {
                    coll.Add("arg4", l.Args[4]);
                }

                // Flags
                foreach (KeyValuePair <string, bool> flag in l.Flags)
                {
                    if (flag.Value)
                    {
                        coll.Add(flag.Key, flag.Value);
                    }
                }

                // Add custom fields
                AddCustomFields(l, "linedef", coll);

                // Store
                textmap.Root.Add("linedef", coll);
            }
        }
示例#9
0
        // This parses a structure in the given data starting
        // from the given pos and line and updates pos and line.
        private UniversalCollection InputStructure(ref string[] data, ref int pos, ref int line, bool topLevel)
        {
            int pm = PM_NOTHING;                                // current parse mode

            key.Remove(0, key.Length);
            val.Remove(0, val.Length);
            bool escape            = false;                     // escape sequence?
            bool endofstruct       = false;                     // true as soon as this level struct ends
            UniversalCollection cs = new UniversalCollection();

            // Go through all of the data until
            // the end or until the struct closes
            // or when an arror occurred
            while ((cpErrorResult == 0) && (endofstruct == false))
            {
                // Get current character
                if (line == data.Length - 1)
                {
                    break;
                }
                if (pos > data[line].Length - 1)
                {
                    pos = 0;
                    line++;
                    if (string.IsNullOrEmpty(data[line]))
                    {
                        continue;                                                      //mxd. Skip empty lines here so correct line number is displayed on errors
                    }
                }

                char c = data[line][pos];                 // current data character

                // ================ What parse mode are we at?
                if (pm == PM_NOTHING)
                {
                    // Now check what character this is
                    switch (c)
                    {
                    case '{':                             // Begin of new struct
                        // Validate key
                        string s = key.ToString().Trim();
                        if (ValidateKey(s, line))
                        {
                            // Next character
                            pos++;

                            // Parse this struct and add it
                            cs.Add(new UniversalEntry(s.ToLowerInvariant(), InputStructure(ref data, ref pos, ref line, false)));

                            // Check the last character
                            pos--;

                            // Reset the key
                            key.Remove(0, key.Length);
                        }

                        // Leave switch
                        break;

                    case '}':                             // End of this struct
                        // Stop parsing in this struct
                        endofstruct = true;

                        // Leave the loop
                        break;

                    case '=':                             // Assignment
                        // Validate key
                        if (ValidateKey(key.ToString().Trim(), line))
                        {
                            // Now parsing assignment
                            pm = PM_ASSIGNMENT;
                        }

                        // Leave switch
                        break;

                    case ';':                             // Terminator

                        // Validate key
                        if (ValidateKey(key.ToString().Trim(), line))
                        {
                            // Error: No value
                            RaiseError(line, ERROR_KEYWITHOUTVALUE);
                        }

                        // Leave switch
                        break;

                    case '\n':                             // New line
                        // Count the line
                        line++;
                        pos = -1;

                        // Add this to the key as a space.
                        // Spaces are not allowed, but it will be trimmed
                        // when its the first or last character.
                        key.Append(" ");

                        // Leave switch
                        break;

                    case '\\':                             // Possible comment
                    case '/':
                        // Check for the line comment //
                        if (data[line].Substring(pos, 2) == "//")
                        {
                            // Skip everything on this line
                            pos = -1;

                            // Have next line?
                            if (line < data.Length - 1)
                            {
                                line++;
                            }
                        }
                        // Check for the block comment /* */
                        else if (data[line].Substring(pos, 2) == "/*")
                        {
                            // Block comment closes on the same line?.. (mxd)
                            int np = data[line].IndexOf("*/", pos);
                            if (np > -1)
                            {
                                pos = np + 1;
                            }
                            else
                            {
                                // Find the next closing block comment
                                line++;
                                while ((np = data[line].IndexOf("*/", 0)) == -1)
                                {
                                    if (line == data.Length - 1)
                                    {
                                        break;
                                    }
                                    line++;
                                }

                                // Closing block comment found?
                                if (np > -1)
                                {
                                    // Skip everything in this block
                                    pos = np + 1;
                                }
                            }
                        }

                        // Leave switch
                        break;

                    default:                             // Everything else
                        if (!topLevel && pos == 0)
                        {
                            while (matches.ContainsKey(data[line]))
                            {
                                cs.Add(matches[data[line]].Key, matches[data[line]].Value);
                                line++;
                                pos = -1;
                            }
                        }

                        // Add character to key
                        if (pos != -1)
                        {
                            key.Append(c);
                        }

                        // Leave switch
                        break;
                    }
                }
                // ================ Parsing an assignment
                else if (pm == PM_ASSIGNMENT)
                {
                    // Check for string opening
                    if (c == '\"')
                    {
                        // Now parsing string
                        pm = PM_STRING;                         //numbers
                    }
                    // Check for numeric character numbers
                    else if (Configuration.NUMBERS2.IndexOf(c) > -1)
                    {
                        // Now parsing number
                        pm = PM_NUMBER;

                        // Go one byte back, because this
                        // byte is part of the number!
                        pos--;
                    }
                    // Check for new line
                    else if (c == '\n')
                    {
                        // Count the new line
                        line++;
                    }
                    // Check if assignment ends
                    else if (c == ';')
                    {
                        // End of assignment
                        pm = PM_NOTHING;

                        // Remove this if it causes problems
                        key.Remove(0, key.Length);
                        val.Remove(0, val.Length);
                    }
                    // Otherwise (if not whitespace) it will be a keyword
                    else if ((c != ' ') && (c != '\t'))
                    {
                        // Now parsing a keyword
                        pm = PM_KEYWORD;

                        // Go one byte back, because this
                        // byte is part of the keyword!
                        pos--;
                    }
                }
                // ================ Parsing a number
                else if (pm == PM_NUMBER)
                {
                    // Check if number ends here
                    if (c == ';')
                    {
                        // Hexadecimal?
                        string s = val.ToString();
                        if ((s.Length > 2) && s.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
                        {
                            // Convert to int
                            try
                            {
                                // Convert to value
                                int ival = Convert.ToInt32(s.Substring(2).Trim(), 16);

                                // Add it to struct
                                UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), ival);
                                cs.Add(entry);
                                if (!matches.ContainsKey(data[line]))
                                {
                                    matches.Add(data[line], entry);
                                }
                            }
                            catch (OverflowException)
                            {
                                // Too large for Int32, try Int64
                                try
                                {
                                    // Convert to value
                                    long lval = Convert.ToInt64(s.Substring(2).Trim(), 16);

                                    // Add it to struct
                                    UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), lval);
                                    cs.Add(entry);
                                    if (!matches.ContainsKey(data[line]))
                                    {
                                        matches.Add(data[line], entry);
                                    }
                                }
                                catch (OverflowException)
                                {
                                    // Too large for Int64, return error
                                    RaiseError(line, ERROR_VALUETOOBIG);
                                }
                                catch (FormatException)
                                {
                                    // ERROR: Invalid value in assignment
                                    RaiseError(line, ERROR_VALUEINVALID + "\n\nUnrecognized token: \"" + s.Trim() + "\"");
                                }
                            }
                            catch (FormatException)
                            {
                                // ERROR: Invalid value in assignment
                                RaiseError(line, ERROR_VALUEINVALID + "\n\nUnrecognized token: \"" + s.Trim() + "\"");
                            }
                        }
                        // Floating point?
                        //mxd. Can be in scientific notation (like "1E-06")
                        else if (s.IndexOf('.') > -1 || s.ToLowerInvariant().Contains("e-"))
                        {
                            double fval = 0;

                            // Convert to float (remove the f first)
                            try { fval = Convert.ToDouble(s.Trim(), CultureInfo.InvariantCulture); }
                            catch (FormatException)
                            {
                                // ERROR: Invalid value in assignment
                                RaiseError(line, ERROR_VALUEINVALID + "\n\nUnrecognized token: \"" + s.Trim() + "\"");
                            }

                            // Add it to struct
                            UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), fval);
                            cs.Add(entry);
                            if (!matches.ContainsKey(data[line]))
                            {
                                matches.Add(data[line], entry);
                            }
                        }
                        else
                        {
                            // Convert to int
                            try
                            {
                                // Convert to value
                                int ival = Convert.ToInt32(s.Trim(), CultureInfo.InvariantCulture);

                                // Add it to struct
                                UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), ival);
                                cs.Add(entry);
                                if (!matches.ContainsKey(data[line]))
                                {
                                    matches.Add(data[line], entry);
                                }
                            }
                            catch (OverflowException)
                            {
                                // Too large for Int32, try Int64
                                try
                                {
                                    // Convert to value
                                    long lval = Convert.ToInt64(s.Trim(), CultureInfo.InvariantCulture);

                                    // Add it to struct
                                    UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), lval);
                                    cs.Add(entry);
                                    if (!matches.ContainsKey(data[line]))
                                    {
                                        matches.Add(data[line], entry);
                                    }
                                }
                                catch (OverflowException)
                                {
                                    // Too large for Int64, return error
                                    RaiseError(line, ERROR_VALUETOOBIG);
                                }
                                catch (FormatException)
                                {
                                    // ERROR: Invalid value in assignment
                                    RaiseError(line, ERROR_VALUEINVALID + "\n\nUnrecognized token: \"" + s.Trim() + "\"");
                                }
                            }
                            catch (FormatException)
                            {
                                // ERROR: Invalid value in assignment
                                RaiseError(line, ERROR_VALUEINVALID + "\n\nUnrecognized token: \"" + s.Trim() + "\"");
                            }
                        }

                        // Reset key and value
                        key.Remove(0, key.Length);
                        val.Remove(0, val.Length);

                        // End of assignment
                        pm = PM_NOTHING;
                    }
                    // Check for new line
                    else if (c == '\n')
                    {
                        // Count the new line
                        line++;
                        pos = -1;
                    }
                    // Everything else is part of the value
                    else
                    {
                        val.Append(c);
                    }
                }
                // ================ Parsing a string
                else if (pm == PM_STRING)
                {
                    // Check if in an escape sequence
                    if (escape)
                    {
                        // What character?
                        switch (c)
                        {
                        case '\\': val.Append('\\'); break;

                        case 'n': val.Append(newline); break;

                        case '\"': val.Append('\"'); break;

                        case 'r': val.Append('\r'); break;

                        case 't': val.Append('\t'); break;

                        default:
                            // Is it a number?
                            if (Configuration.NUMBERS.IndexOf(c) > -1)
                            {
                                int  vv = 0;
                                char vc = '0';

                                // Convert the next 3 characters to a number
                                string v = data[line].Substring(pos, 3);
                                try { vv = Convert.ToInt32(v.Trim(), CultureInfo.InvariantCulture); }
                                catch (FormatException)
                                {
                                    // ERROR: Invalid value in assignment
                                    RaiseError(line, ERROR_VALUEINVALID + "\n\nUnrecognized token: \"" + v.Trim() + "\"");
                                }

                                // Convert the number to a char
                                try { vc = Convert.ToChar(vv, CultureInfo.InvariantCulture); }
                                catch (FormatException)
                                {
                                    // ERROR: Invalid value in assignment
                                    RaiseError(line, ERROR_VALUEINVALID + "\n\nUnrecognized token: \"" + v.Trim() + "\"");
                                }

                                // Add the char
                                val.Append(vc);
                            }
                            else
                            {
                                // Add the character as it is
                                val.Append(c);
                            }

                            // Leave switch
                            break;
                        }

                        // End of escape sequence
                        escape = false;
                    }
                    else
                    {
                        // Check for sequence start
                        if (c == '\\')
                        {
                            // Next character is of escape sequence
                            escape = true;
                        }
                        // Check if string ends
                        else if (c == '\"')
                        {
                            // Add string to struct
                            UniversalEntry entry = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), val.ToString());
                            cs.Add(entry);
                            if (!matches.ContainsKey(data[line]))
                            {
                                matches.Add(data[line], entry);
                            }

                            // End of assignment
                            pm = PM_ASSIGNMENT;

                            // Reset key and value
                            key.Remove(0, key.Length);
                            val.Remove(0, val.Length);
                        }
                        // Check for new line
                        else if (c == '\n')
                        {
                            // Count the new line
                            line++;
                            pos = -1;
                        }
                        // Everything else is just part of string
                        else
                        {
                            // Add to value
                            val.Append(c);
                        }
                    }
                }
                // ================ Parsing a keyword
                else if (pm == PM_KEYWORD)
                {
                    // Check if keyword ends
                    if (c == ';')
                    {
                        // Add to the struct depending on the keyword
                        switch (val.ToString().Trim().ToLowerInvariant())
                        {
                        case "true":
                            // Add boolean true
                            UniversalEntry t = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), true);
                            cs.Add(t);
                            if (!matches.ContainsKey(data[line]))
                            {
                                matches.Add(data[line], t);
                            }
                            break;

                        case "false":
                            // Add boolean false
                            UniversalEntry f = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), false);
                            cs.Add(f);
                            if (!matches.ContainsKey(data[line]))
                            {
                                matches.Add(data[line], f);
                            }
                            break;

                        case "nan":
                            // Add float value
                            UniversalEntry nan = new UniversalEntry(key.ToString().Trim().ToLowerInvariant(), double.NaN);
                            // Do not add NaN, just drop it with a warning
                            // cs.Add(nan);
                            warnings.Add("UDMF map data line " + (line + 1) + ": value of field " + key.ToString().Trim().ToLowerInvariant() + " has a value of NaN (not a number). Field is being dropped permanently.");
                            if (!matches.ContainsKey(data[line]))
                            {
                                matches.Add(data[line], nan);
                            }
                            break;

                        default:
                            // Unknown keyword
                            RaiseError(line, ERROR_KEYWORDUNKNOWN + "\n\nUnrecognized token: \"" + val.ToString().Trim() + "\"");
                            break;
                        }

                        // End of assignment
                        pm = PM_NOTHING;

                        // Reset key and value
                        key.Remove(0, key.Length);
                        val.Remove(0, val.Length);
                    }
                    // Check for new line
                    else if (c == '\n')
                    {
                        // Count the new line
                        line++;
                        pos = -1;
                    }
                    // Everything else is just part of keyword
                    else
                    {
                        // Add to value
                        val.Append(c);
                    }
                }

                // Next character
                pos++;
            }

            // Return the parsed result
            return(cs);
        }
示例#10
0
        // This parses a structure in the given data starting
        // from the given pos and line and updates pos and line.
        private UniversalCollection InputStructure(ref string data, ref int pos, ref int line)
        {
            char c  = '\0';                                     // current data character
            int  pm = PM_NOTHING;                               // current parse mode
            //string key = "", val = "";		// current key and value beign built
            bool escape               = false;                  // escape sequence?
            bool endofstruct          = false;                  // true as soon as this level struct ends
            UniversalCollection cs    = new UniversalCollection();
            StringBuilder       keysb = new StringBuilder(32);
            StringBuilder       valsb = new StringBuilder(32);

            // Go through all of the data until
            // the end or until the struct closes
            // or when an arror occurred
            while ((pos < data.Length) && (cpErrorResult == 0) && (endofstruct == false))
            {
                // Get current character
                c = data[pos];

                // ================ What parse mode are we at?
                if (pm == PM_NOTHING)
                {
                    // Now check what character this is
                    switch (c)
                    {
                    case '{':                             // Begin of new struct

                        // Validate key
                    {
                        string key = keysb.ToString().Trim();
                        if (ValidateKey(key, line))
                        {
                            // Next character
                            pos++;

                            // Parse this struct and add it
                            cs.Add(new UniversalEntry(key, InputStructure(ref data, ref pos, ref line)));

                            // Check the last character
                            pos--;

                            // Reset the key
                            keysb.Length = 0;
                        }
                    }

                        // Leave switch
                        break;

                    case '}':                             // End of this struct

                        // Stop parsing in this struct
                        endofstruct = true;

                        // Leave the loop
                        break;

                    case '=':                             // Assignment

                        // Validate key
                        if (ValidateKey(keysb.ToString().Trim(), line))
                        {
                            // Now parsing assignment
                            pm = PM_ASSIGNMENT;
                        }

                        // Leave switch
                        break;

                    case ';':                             // Terminator

                        // Validate key
                        if (ValidateKey(keysb.ToString().Trim(), line))
                        {
                            // Error: No value
                            RaiseError(line, ERROR_KEYWITHOUTVALUE);
                        }

                        // Leave switch
                        break;

                    case '\n':                             // New line

                        // Count the line
                        line++;

                        // Add this to the key as a space.
                        // Spaces are not allowed, but it will be trimmed
                        // when its the first or last character.
                        keysb.Append(' ');

                        // Leave switch
                        break;

                    case '\\':                             // Possible comment
                    case '/':

                        // Check for the line comment //
                        if (data.Substring(pos, 2) == "//")
                        {
                            // Find the next line
                            int np = data.IndexOf("\n", pos);

                            // Next line found?
                            if (np > -1)
                            {
                                // Count the line
                                line++;

                                // Skip everything on this line
                                pos = np;
                            }
                            else
                            {
                                // No end of line
                                // Skip everything else
                                pos = data.Length;
                            }
                        }
                        // Check for the block comment /* */
                        else if (data.Substring(pos, 2) == "/*")
                        {
                            // Find the next closing block comment
                            int np = data.IndexOf("*/", pos);

                            // Closing block comment found?
                            if (np > -1)
                            {
                                // Count the lines in the block comment
                                string blockdata = data.Substring(pos, np - pos + 2);
                                line += (blockdata.Split("\n".ToCharArray()).Length - 1);

                                // Skip everything in this block
                                pos = np + 1;
                            }
                            else
                            {
                                // No end of line
                                // Skip everything else
                                pos = data.Length;
                            }
                        }

                        // Leave switch
                        break;

                    default:                             // Everything else

                        // Add character to key
                        keysb.Append(char.ToLowerInvariant(c));

                        // Leave switch
                        break;
                    }
                }
                // ================ Parsing an assignment
                else if (pm == PM_ASSIGNMENT)
                {
                    // Check for string opening
                    if (c == '\"')
                    {
                        // Now parsing string
                        pm = PM_STRING;
                    }
                    // Check for numeric character
                    //else if("0123456789-.&".IndexOf(c.ToString(CultureInfo.InvariantCulture)) > -1)
                    else if ((c >= '0' && c <= '9') || c == '&' || c == '-' || c == '.')
                    {
                        // Now parsing number
                        pm = PM_NUMBER;

                        // Go one byte back, because this
                        // byte is part of the number!
                        pos--;
                    }
                    // Check for new line
                    else if (c == '\n')
                    {
                        // Count the new line
                        line++;
                    }
                    // Check if assignment ends
                    else if (c == ';')
                    {
                        // End of assignment
                        pm = PM_NOTHING;

                        // Remove this if it causes problems
                        keysb.Length = 0;
                        valsb.Length = 0;
                    }
                    // Otherwise (if not whitespace) it will be a keyword
                    else if ((c != ' ') && (c != '\t'))
                    {
                        // Now parsing a keyword
                        pm = PM_KEYWORD;

                        // Go one byte back, because this
                        // byte is part of the keyword!
                        pos--;
                    }
                }
                // ================ Parsing a number
                else if (pm == PM_NUMBER)
                {
                    // Check if number ends here
                    if (c == ';')
                    {
                        string val = valsb.ToString().Trim();
                        string key = keysb.ToString().Trim();
                        // Hexadecimal?
                        if ((val.Length > 2) && val.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase))
                        {
                            int  ival = 0;
                            long lval = 0;

                            // Convert to int
                            try
                            {
                                // Convert to value
                                ival = System.Convert.ToInt32(val.Substring(2), 16);

                                // Add it to struct
                                cs.Add(new UniversalEntry(key, ival));
                            }
                            catch (System.OverflowException)
                            {
                                // Too large for Int32, try Int64
                                try
                                {
                                    // Convert to value
                                    lval = System.Convert.ToInt64(val.Substring(2), 16);

                                    // Add it to struct
                                    cs.Add(new UniversalEntry(key, lval));
                                }
                                catch (System.OverflowException)
                                {
                                    // Too large for Int64, return error
                                    RaiseError(line, ERROR_VALUETOOBIG);
                                }
                                catch (System.FormatException)
                                {
                                    // ERROR: Invalid value in assignment
                                    RaiseError(line, ERROR_VALUEINVALID);
                                }
                            }
                            catch (System.FormatException)
                            {
                                // ERROR: Invalid value in assignment
                                RaiseError(line, ERROR_VALUEINVALID);
                            }
                        }
                        // Floating point?
                        else if (val.IndexOf(".") > -1)
                        {
                            float fval = 0;

                            // Convert to float (remove the f first)
                            try { fval = System.Convert.ToSingle(val, CultureInfo.InvariantCulture); }
                            catch (System.FormatException)
                            {
                                // ERROR: Invalid value in assignment
                                RaiseError(line, ERROR_VALUEINVALID);
                            }

                            // Add it to struct
                            cs.Add(new UniversalEntry(key, fval));
                        }
                        else
                        {
                            int  ival = 0;
                            long lval = 0;

                            // Convert to int
                            try
                            {
                                // Convert to value
                                ival = System.Convert.ToInt32(val, CultureInfo.InvariantCulture);

                                // Add it to struct
                                cs.Add(new UniversalEntry(key, ival));
                            }
                            catch (System.OverflowException)
                            {
                                // Too large for Int32, try Int64
                                try
                                {
                                    // Convert to value
                                    lval = System.Convert.ToInt64(val, CultureInfo.InvariantCulture);

                                    // Add it to struct
                                    cs.Add(new UniversalEntry(key, lval));
                                }
                                catch (System.OverflowException)
                                {
                                    // Too large for Int64, return error
                                    RaiseError(line, ERROR_VALUETOOBIG);
                                }
                                catch (System.FormatException)
                                {
                                    // ERROR: Invalid value in assignment
                                    RaiseError(line, ERROR_VALUEINVALID);
                                }
                            }
                            catch (System.FormatException)
                            {
                                // ERROR: Invalid value in assignment
                                RaiseError(line, ERROR_VALUEINVALID);
                            }
                        }

                        // Reset key and value
                        keysb.Length = 0;
                        valsb.Length = 0;

                        // End of assignment
                        pm = PM_NOTHING;
                    }
                    // Check for new line
                    else if (c == '\n')
                    {
                        // Count the new line
                        line++;
                    }
                    // Everything else is part of the value
                    else
                    {
                        valsb.Append(char.ToLowerInvariant(c));
                    }
                }
                // ================ Parsing a string
                else if (pm == PM_STRING)
                {
                    // Check if in an escape sequence
                    if (escape)
                    {
                        // What character?
                        switch (c)
                        {
                        case '\\': valsb.Append('\\'); break;

                        case 'n': valsb.Append('\n'); break;

                        case '\"': valsb.Append('\"'); break;

                        case 'r': valsb.Append('\r'); break;

                        case 't': valsb.Append('\t'); break;

                        default:

                            // Is it a number?
                            //if("0123456789".IndexOf(c.ToString(CultureInfo.InvariantCulture)) > -1)
                            if (c >= '0' && c <= '9')
                            {
                                int  vv = 0;
                                char vc = '0';

                                // Convert the next 3 characters to a number
                                string v = data.Substring(pos, 3);
                                try { vv = System.Convert.ToInt32(v.Trim(), CultureInfo.InvariantCulture); }
                                catch (System.FormatException)
                                {
                                    // ERROR: Invalid value in assignment
                                    RaiseError(line, ERROR_VALUEINVALID);
                                }

                                // Convert the number to a char
                                try { vc = System.Convert.ToChar(vv, CultureInfo.InvariantCulture); }
                                catch (System.FormatException)
                                {
                                    // ERROR: Invalid value in assignment
                                    RaiseError(line, ERROR_VALUEINVALID);
                                }

                                // Add the char
                                valsb.Append(Char.ToLowerInvariant(vc));
                            }
                            else
                            {
                                // Add the character as it is
                                valsb.Append(c);
                            }

                            // Leave switch
                            break;
                        }

                        // End of escape sequence
                        escape = false;
                    }
                    else
                    {
                        // Check for sequence start
                        if (c == '\\')
                        {
                            // Next character is of escape sequence
                            escape = true;
                        }
                        // Check if string ends
                        else if (c == '\"')
                        {
                            // Add string to struct
                            cs.Add(new UniversalEntry(keysb.ToString().Trim(), valsb.ToString()));

                            // End of assignment
                            pm = PM_ASSIGNMENT;

                            // Reset key and value
                            keysb.Length = 0;
                            valsb.Length = 0;
                        }
                        // Check for new line
                        else if (c == '\n')
                        {
                            // Count the new line
                            line++;
                        }
                        // Everything else is just part of string
                        else
                        {
                            // Add to value
                            valsb.Append(c);
                        }
                    }
                }
                // ================ Parsing a keyword
                else if (pm == PM_KEYWORD)
                {
                    // Check if keyword ends
                    if (c == ';')
                    {
                        // Add to the struct depending on the keyword
                        switch (valsb.ToString().Trim().ToLowerInvariant())
                        {
                        case "true":

                            // Add boolean true
                            cs.Add(new UniversalEntry(keysb.ToString().Trim(), true));
                            break;

                        case "false":

                            // Add boolean false
                            cs.Add(new UniversalEntry(keysb.ToString().Trim(), false));
                            break;

                        default:

                            // Unknown keyword
                            RaiseError(line, ERROR_KEYWORDUNKNOWN);
                            break;
                        }

                        // End of assignment
                        pm = PM_NOTHING;

                        // Reset key and value
                        keysb.Length = 0;
                        valsb.Length = 0;
                    }
                    // Check for new line
                    else if (c == '\n')
                    {
                        // Count the new line
                        line++;
                    }
                    // Everything else is just part of keyword
                    else
                    {
                        // Add to value
                        valsb.Append(c);
                    }
                }

                // Next character
                pos++;
            }

            // Return the parsed result
            return(cs);
        }
示例#11
0
        // This adds sectors
        private void WriteSectors(ICollection <Sector> sectors, UniversalParser textmap)
        {
            // Go for all sectors
            foreach (Sector s in sectors)
            {
                // Make collection
                UniversalCollection coll = new UniversalCollection();
                coll.Add("heightfloor", s.FloorHeight);
                coll.Add("heightceiling", s.CeilHeight);
                coll.Add("texturefloor", s.FloorTexture);
                coll.Add("textureceiling", s.CeilTexture);
                coll.Add("lightlevel", s.Brightness);
                if (s.Effect != 0)
                {
                    coll.Add("special", s.Effect);
                }
                if (s.Tag != 0)
                {
                    coll.Add("id", s.Tag);
                }

                // villsa 9/14/11 (builder64)
                coll.Add("color1", s.FloorColor.color.ToInt());
                coll.Add("color2", s.CeilColor.color.ToInt());
                coll.Add("color3", s.ThingColor.color.ToInt());
                coll.Add("color4", s.TopColor.color.ToInt());
                coll.Add("color5", s.LowerColor.color.ToInt());

                // villsa 9/13/11 - Flags
                foreach (KeyValuePair <string, bool> flag in s.Flags)
                {
                    if (flag.Value)
                    {
                        coll.Add(flag.Key, flag.Value);
                    }
                }

                coll.Comment = s.Index.ToString();

                // Add custom fields
                AddCustomFields(s, "sector", coll);

                // Store
                textmap.Root.Add("sector", coll);
            }
        }
        // This adds sectors
        private void WriteSectors(ICollection <Sector> sectors, UniversalParser textmap)
        {
            // Go for all sectors
            foreach (Sector s in sectors)
            {
                // Make collection
                UniversalCollection coll = new UniversalCollection();
                coll.Add("heightfloor", s.FloorHeight);
                coll.Add("heightceiling", s.CeilHeight);
                coll.Add("texturefloor", s.FloorTexture);
                coll.Add("textureceiling", s.CeilTexture);
                coll.Add("lightlevel", s.Brightness);
                if (s.Effect != 0)
                {
                    coll.Add("special", s.Effect);
                }
                if (s.Tag != 0)
                {
                    coll.Add("id", s.Tag);
                }
                coll.Comment = s.Index.ToString();

                //mxd. MoreIDs
                if (s.Tags.Count > 1)                //first entry is saved as "id"
                {
                    string[] moreidscol = new string[s.Tags.Count - 1];
                    for (int i = 1; i < s.Tags.Count; i++)
                    {
                        moreidscol[i - 1] = s.Tags[i].ToString();
                    }
                    coll.Add("moreids", string.Join(" ", moreidscol));
                }

                //mxd. Slopes
                if (s.FloorSlope.GetLengthSq() > 0)
                {
                    coll.Add("floorplane_a", Math.Round(s.FloorSlope.x, Sector.SLOPE_DECIMALS));
                    coll.Add("floorplane_b", Math.Round(s.FloorSlope.y, Sector.SLOPE_DECIMALS));
                    coll.Add("floorplane_c", Math.Round(s.FloorSlope.z, Sector.SLOPE_DECIMALS));
                    coll.Add("floorplane_d",
                             (float.IsNaN(s.FloorSlopeOffset) ? 0f : Math.Round(s.FloorSlopeOffset, Sector.SLOPE_DECIMALS)));
                }

                if (s.CeilSlope.GetLengthSq() > 0)
                {
                    coll.Add("ceilingplane_a", Math.Round(s.CeilSlope.x, Sector.SLOPE_DECIMALS));
                    coll.Add("ceilingplane_b", Math.Round(s.CeilSlope.y, Sector.SLOPE_DECIMALS));
                    coll.Add("ceilingplane_c", Math.Round(s.CeilSlope.z, Sector.SLOPE_DECIMALS));
                    coll.Add("ceilingplane_d",
                             (float.IsNaN(s.CeilSlopeOffset) ? 0f : Math.Round(s.CeilSlopeOffset, Sector.SLOPE_DECIMALS)));
                }

                //mxd. Flags
                foreach (KeyValuePair <string, bool> flag in s.Flags)
                {
                    if (flag.Value)
                    {
                        coll.Add(flag.Key, flag.Value);
                    }
                }

                // Add custom fields
                AddCustomFields(s, "sector", coll);

                // Store
                textmap.Root.Add("sector", coll);
            }
        }