// This reads the linedefs and sidedefs private static void ReadLines(MapSet map, BinaryReader reader, Dictionary <int, Vertex> vertexlink, Dictionary <int, BuildSector> sectorlink, Dictionary <int, BuildWall> sidedeflink) { int count = reader.ReadInt32(); // Go for all lines map.SetCapacity(0, map.Linedefs.Count + count, map.Sidedefs.Count + sidedeflink.Count, 0, 0); for (int i = 0; i < count; i++) { int v1 = reader.ReadInt32(); int v2 = reader.ReadInt32(); int s1 = reader.ReadInt32(); int s2 = reader.ReadInt32(); // Check if not zero-length if (Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f) { // Create new linedef Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); if (l != null) { l.Update(); l.UpdateCache(); // Connect walls to the line if (s1 > -1) { if (s1 < sidedeflink.Count) { AddWall(map, sidedeflink[s1], l, true, sectorlink); } else { General.ErrorLogger.Add(ErrorType.Warning, "Line " + i + " references invalid front wall " + s1 + ". Wall has been removed."); } } if (s2 > -1) { if (s2 < sidedeflink.Count) { AddWall(map, sidedeflink[s2], l, false, sectorlink); } else { General.ErrorLogger.Add(ErrorType.Warning, "Line " + i + " references invalid back wall " + s1 + ". Wall has been removed."); } } } } else { General.ErrorLogger.Add(ErrorType.Warning, "Line " + i + " is zero-length. Line has been removed."); } } }
// This reads the LINEDEFS and SIDEDEFS from WAD file private void ReadLinedefs(MapSet map, int firstindex, Dictionary <int, Vertex> vertexlink, Dictionary <int, Sector> sectorlink) { int[] args = new int[Linedef.NUM_ARGS]; // Get the linedefs lump from wad file Lump linedefslump = wad.FindLump("LINEDEFS", firstindex); if (linedefslump == null) { throw new Exception("Could not find required lump LINEDEFS!"); } // Get the sidedefs lump from wad file Lump sidedefslump = wad.FindLump("SIDEDEFS", firstindex); if (sidedefslump == null) { throw new Exception("Could not find required lump SIDEDEFS!"); } // Prepare to read the items MemoryStream linedefsmem = new MemoryStream(linedefslump.Stream.ReadAllBytes()); MemoryStream sidedefsmem = new MemoryStream(sidedefslump.Stream.ReadAllBytes()); int num = (int)linedefslump.Stream.Length / 16; int numsides = (int)sidedefslump.Stream.Length / 30; BinaryReader readline = new BinaryReader(linedefsmem); BinaryReader readside = new BinaryReader(sidedefsmem); // Read items from the lump map.SetCapacity(0, map.Linedefs.Count + num, map.Sidedefs.Count + numsides, 0, 0); for (int i = 0; i < num; i++) { // Read properties from stream int v1 = readline.ReadUInt16(); int v2 = readline.ReadUInt16(); int flags = readline.ReadUInt16(); int action = readline.ReadByte(); args[0] = readline.ReadByte(); args[1] = readline.ReadByte(); args[2] = readline.ReadByte(); args[3] = readline.ReadByte(); args[4] = readline.ReadByte(); int s1 = readline.ReadUInt16(); int s2 = readline.ReadUInt16(); // Make string flags Dictionary <string, bool> stringflags = new Dictionary <string, bool>(StringComparer.Ordinal); foreach (string f in manager.Config.SortedLinedefFlags) { int fnum; if (int.TryParse(f, out fnum)) { stringflags[f] = ((flags & fnum) == fnum); } } // Create new linedef if (vertexlink.ContainsKey(v1) && vertexlink.ContainsKey(v2)) { // Check if not zero-length if (Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f) { Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); l.Update(stringflags, (flags & manager.Config.LinedefActivationsFilter), new List <int> { 0 }, action, args); l.UpdateCache(); Sidedef s; string thigh, tmid, tlow; int offsetx, offsety, sc; // Line has a front side? if (s1 != ushort.MaxValue) { // Read front sidedef sidedefsmem.Seek(s1 * 30, SeekOrigin.Begin); if ((s1 * 30L) <= (sidedefsmem.Length - 30L)) { offsetx = readside.ReadInt16(); offsety = readside.ReadInt16(); thigh = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); tlow = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); tmid = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); sc = readside.ReadUInt16(); // Create front sidedef if (sectorlink.ContainsKey(sc)) { s = map.CreateSidedef(l, true, sectorlink[sc]); s.Update(offsetx, offsety, thigh, tmid, tlow); } else { General.ErrorLogger.Add(ErrorType.Warning, "Sidedef " + s1 + " references invalid sector " + sc + ". Sidedef has been removed."); } } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid sidedef " + s1 + ". Sidedef has been removed."); } } // Line has a back side? if (s2 != ushort.MaxValue) { // Read back sidedef sidedefsmem.Seek(s2 * 30, SeekOrigin.Begin); if ((s2 * 30L) <= (sidedefsmem.Length - 30L)) { offsetx = readside.ReadInt16(); offsety = readside.ReadInt16(); thigh = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); tlow = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); tmid = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); sc = readside.ReadUInt16(); // Create back sidedef if (sectorlink.ContainsKey(sc)) { s = map.CreateSidedef(l, false, sectorlink[sc]); s.Update(offsetx, offsety, thigh, tmid, tlow); } else { General.ErrorLogger.Add(ErrorType.Warning, "Sidedef " + s2 + " references invalid sector " + sc + ". Sidedef has been removed."); } } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid sidedef " + s2 + ". Sidedef has been removed."); } } } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed."); } } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references one or more invalid vertices. Linedef has been removed."); } } // Done linedefsmem.Dispose(); sidedefsmem.Dispose(); }
// This reads the linedefs and sidedefs private static void ReadLinedefs(MapSet map, BinaryReader reader, Dictionary <int, Vertex> vertexlink, Dictionary <int, Sector> sectorlink, Dictionary <int, SidedefData> sidedeflink) { int count = reader.ReadInt32(); // Go for all lines map.SetCapacity(0, map.Linedefs.Count + count, map.Sidedefs.Count + sidedeflink.Count, 0, 0); for (int i = 0; i < count; i++) { int[] args = new int[Linedef.NUM_ARGS]; int v1 = reader.ReadInt32(); int v2 = reader.ReadInt32(); int s1 = reader.ReadInt32(); int s2 = reader.ReadInt32(); int special = reader.ReadInt32(); for (int a = 0; a < Linedef.NUM_ARGS; a++) { args[a] = reader.ReadInt32(); } int numtags = reader.ReadInt32(); //mxd List <int> tags = new List <int>(numtags); //mxd for (int a = 0; a < numtags; a++) { tags.Add(reader.ReadInt32()); //mxd } //flags Dictionary <string, bool> stringflags = new Dictionary <string, bool>(StringComparer.Ordinal); int numFlags = reader.ReadInt32(); for (int f = 0; f < numFlags; f++) { stringflags.Add(ReadString(reader), reader.ReadBoolean()); } //add missing flags foreach (KeyValuePair <string, string> flag in General.Map.Config.LinedefFlags) { if (stringflags.ContainsKey(flag.Key)) { continue; } stringflags.Add(flag.Key, false); } //add missing activations foreach (LinedefActivateInfo activate in General.Map.Config.LinedefActivates) { if (stringflags.ContainsKey(activate.Key)) { continue; } stringflags.Add(activate.Key, false); } // Read custom fields Dictionary <string, UniValue> fields = ReadCustomFields(reader); // Check if not zero-length if (Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f) { // Create new linedef Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); if (l != null) { l.Update(stringflags, 0, tags, special, args); l.UpdateCache(); // Add custom fields l.Fields.BeforeFieldsChange(); foreach (KeyValuePair <string, UniValue> group in fields) { l.Fields.Add(group.Key, group.Value); } // Connect sidedefs to the line if (s1 > -1) { if (s1 < sidedeflink.Count) { AddSidedef(map, sidedeflink[s1], l, true, sectorlink); } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid front sidedef " + s1 + ". Sidedef has been removed."); } } if (s2 > -1) { if (s2 < sidedeflink.Count) { AddSidedef(map, sidedeflink[s2], l, false, sectorlink); } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid back sidedef " + s1 + ". Sidedef has been removed."); } } } } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed."); } } }
// This reads the linedefs and sidedefs private void ReadLinedefs(MapSet map, UniversalParser textmap, Dictionary <int, Vertex> vertexlink, Dictionary <int, Sector> sectorlink) { // Get list of entries List <UniversalCollection> linescolls = GetNamedCollections(textmap.Root, "linedef"); List <UniversalCollection> sidescolls = GetNamedCollections(textmap.Root, "sidedef"); // Go for all lines map.SetCapacity(0, map.Linedefs.Count + linescolls.Count, map.Sidedefs.Count + sidescolls.Count, 0, 0); char[] splitter = { ' ' }; //mxd for (int i = 0; i < linescolls.Count; i++) { // Read fields UniversalCollection lc = linescolls[i]; int[] args = new int[Linedef.NUM_ARGS]; string where = "linedef " + i; int v1 = GetCollectionEntry(lc, "v1", true, 0, where); int v2 = GetCollectionEntry(lc, "v2", true, 0, where); if (!vertexlink.ContainsKey(v1) || !vertexlink.ContainsKey(v2)) { //mxd General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references one or more invalid vertices. Linedef has been removed."); continue; } int tag = GetCollectionEntry(lc, "id", false, 0, where); int special = GetCollectionEntry(lc, "special", false, 0, where); args[0] = GetCollectionEntry(lc, "arg0", false, 0, where); args[1] = GetCollectionEntry(lc, "arg1", false, 0, where); args[2] = GetCollectionEntry(lc, "arg2", false, 0, where); args[3] = GetCollectionEntry(lc, "arg3", false, 0, where); args[4] = GetCollectionEntry(lc, "arg4", false, 0, where); int s1 = GetCollectionEntry(lc, "sidefront", false, -1, where); int s2 = GetCollectionEntry(lc, "sideback", false, -1, where); //mxd. MoreIDs List <int> tags = new List <int> { tag }; string moreids = GetCollectionEntry(lc, "moreids", false, string.Empty, where); if (!string.IsNullOrEmpty(moreids)) { string[] moreidscol = moreids.Split(splitter, StringSplitOptions.RemoveEmptyEntries); foreach (string sid in moreidscol) { int id; if (int.TryParse(sid.Trim(), out id) && id != 0 && !tags.Contains(id)) { tags.Add(id); } } } if (tag == 0 && tags.Count > 1) { tags.RemoveAt(0); } // Flags Dictionary <string, bool> stringflags = new Dictionary <string, bool>(StringComparer.Ordinal); foreach (KeyValuePair <string, string> flag in General.Map.Config.LinedefFlags) { stringflags[flag.Key] = GetCollectionEntry(lc, flag.Key, false, false, where); } foreach (FlagTranslation ft in General.Map.Config.LinedefFlagsTranslation) { foreach (string field in ft.Fields) { stringflags[field] = GetCollectionEntry(lc, field, false, false, where); } } // Activations foreach (LinedefActivateInfo activate in General.Map.Config.LinedefActivates) { stringflags[activate.Key] = GetCollectionEntry(lc, activate.Key, false, false, where); } // Check if not zero-length if (Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f) { // Create new linedef Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); if (l != null) { l.Update(stringflags, 0, tags, special, args); l.UpdateCache(); // Custom fields ReadCustomFields(lc, l, "linedef"); // Read sidedefs and connect them to the line if (s1 > -1) { if (s1 < sidescolls.Count) { ReadSidedef(map, sidescolls[s1], l, true, sectorlink, s1); } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid front sidedef " + s1 + ". Sidedef has been removed."); } } if (s2 > -1) { if (s2 < sidescolls.Count) { ReadSidedef(map, sidescolls[s2], l, false, sectorlink, s2); } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid back sidedef " + s1 + ". Sidedef has been removed."); } } } } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed."); } } }
private static void CreateWalls(MapSet map, List <BuildWall> walls, List <BuildSector> sectors) { // Count how many lines and walls we will actually create... int numwalls = walls.Count; int numdoublesidedwalls = 0; foreach (BuildWall w in walls) { if (w == null) { numwalls--; } else if (w.OtherWallIndex > -1) { numdoublesidedwalls++; } } int numlines = numwalls - (numdoublesidedwalls / 2); // Walls are stored per-sector map.SetCapacity(0, map.Linedefs.Count + numlines, map.Sidedefs.Count + numwalls, 0, 0); Dictionary <int, Linedef> newlines = new Dictionary <int, Linedef>(); // <wall index, line> int walloffset = 0; foreach (BuildSector bs in sectors) { for (int i = walloffset; i < walloffset + bs.WallsCount; i++) { BuildWall w = walls[i]; if (w == null) { continue; } // Line already created? if (w.OtherWallIndex > -1 && newlines.ContainsKey(w.OtherWallIndex)) { // Add back side Sidedef back = map.CreateSidedef(newlines[w.OtherWallIndex], false, bs.Sector); back.Update(w); w.Side = back; } else { // Create line Linedef l = map.CreateLinedef(w.Start, w.End); l.Update(); l.UpdateCache(); // Add front side Sidedef front = map.CreateSidedef(l, true, bs.Sector); front.Update(w); w.Side = front; // Add to collection newlines[i] = l; } } walloffset += bs.WallsCount; } // Set Sector FirstWalls for (int i = 0; i < sectors.Count; i++) { int wallindex = sectors[i].FirstWallIndex; if (wallindex < 0 || wallindex >= walls.Count) { General.ErrorLogger.Add(ErrorType.Error, "Failed to set First Wall " + wallindex + " of sector " + i + ": corresponding wall does not exist!"); } else { sectors[i].Sector.FirstWall = walls[wallindex].Side; } } }
// This reads the linedefs and sidedefs private void ReadLinedefs(MapSet map, UniversalParser textmap, Dictionary <int, Vertex> vertexlink, Dictionary <int, Sector> sectorlink) { // Get list of entries List <UniversalCollection> linescolls = GetNamedCollections(textmap.Root, "linedef"); List <UniversalCollection> sidescolls = GetNamedCollections(textmap.Root, "sidedef"); // Go for all lines map.SetCapacity(0, map.Linedefs.Count + linescolls.Count, map.Sidedefs.Count + sidescolls.Count, 0, 0); for (int i = 0; i < linescolls.Count; i++) { // Read fields UniversalCollection lc = linescolls[i]; int[] args = new int[Linedef.NUM_ARGS]; string where = "linedef " + i; int tag = GetCollectionEntry <int>(lc, "id", false, 0, where); int v1 = GetCollectionEntry <int>(lc, "v1", true, 0, where); int v2 = GetCollectionEntry <int>(lc, "v2", true, 0, where); int special = GetCollectionEntry <int>(lc, "special", false, 0, where); int acti = GetCollectionEntry <int>(lc, "activate", false, 0, where); // villsa 9/13/11 int switchmask = GetCollectionEntry <int>(lc, "switchmask", false, 0, where); // villsa 9/13/11 args[0] = GetCollectionEntry <int>(lc, "arg0", false, 0, where); args[1] = GetCollectionEntry <int>(lc, "arg1", false, 0, where); args[2] = GetCollectionEntry <int>(lc, "arg2", false, 0, where); args[3] = GetCollectionEntry <int>(lc, "arg3", false, 0, where); args[4] = GetCollectionEntry <int>(lc, "arg4", false, 0, where); int s1 = GetCollectionEntry <int>(lc, "sidefront", true, -1, where); int s2 = GetCollectionEntry <int>(lc, "sideback", false, -1, where); // Flags Dictionary <string, bool> stringflags = new Dictionary <string, bool>(); foreach (KeyValuePair <string, string> flag in General.Map.Config.LinedefFlags) { stringflags[flag.Key] = GetCollectionEntry <bool>(lc, flag.Key, false, false, where); } foreach (FlagTranslation ft in General.Map.Config.LinedefFlagsTranslation) { foreach (string field in ft.Fields) { stringflags[field] = GetCollectionEntry <bool>(lc, field, false, false, where); } } // Activations foreach (LinedefActivateInfo activate in General.Map.Config.LinedefActivates) { stringflags[activate.Key] = GetCollectionEntry <bool>(lc, activate.Key, false, false, where); } // Create new linedef if (vertexlink.ContainsKey(v1) && vertexlink.ContainsKey(v2)) { // Check if not zero-length if (Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f) { Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); if (l != null) { l.Update(stringflags, acti, tag, special, switchmask, args); l.UpdateCache(); // Custom fields ReadCustomFields(lc, l, "linedef"); // Read sidedefs and connect them to the line if (s1 > -1) { if (s1 < sidescolls.Count) { ReadSidedef(map, sidescolls[s1], l, true, sectorlink, s1); } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid front sidedef " + s1 + ". Sidedef has been removed."); } } if (s2 > -1) { if (s2 < sidescolls.Count) { ReadSidedef(map, sidescolls[s2], l, false, sectorlink, s2); } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid back sidedef " + s1 + ". Sidedef has been removed."); } } } } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed."); } } else { General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references one or more invalid vertices. Linedef has been removed."); } } }