// 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); } }
// 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); } }
// 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); }
// 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); }
// 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); } }