// This splits this line by vertex v // Returns the new line resulting from the split, or null when it failed public Linedef Split(Vertex v) { Linedef nl; Sidedef nsd; if (v == null) { return(null); } // Copy linedef and change vertices nl = map.CreateLinedef(v, end); if (nl == null) { return(null); } CopyPropertiesTo(nl); SetEndVertex(v); nl.Selected = this.Selected; nl.marked = this.marked; // Copy front sidedef if exists if (front != null) { nsd = map.CreateSidedef(nl, true, front.Sector); if (nsd == null) { return(null); } front.CopyPropertiesTo(nsd); nsd.Marked = front.Marked; // Make texture offset adjustments nsd.OffsetX += (int)Vector2D.Distance(this.start.Position, this.end.Position); } // Copy back sidedef if exists if (back != null) { nsd = map.CreateSidedef(nl, false, back.Sector); if (nsd == null) { return(null); } back.CopyPropertiesTo(nsd); nsd.Marked = back.Marked; // Make texture offset adjustments back.OffsetX += (int)Vector2D.Distance(nl.start.Position, nl.end.Position); } // Return result General.Map.IsChanged = true; return(nl); }
// This reads a single sidedef and connects it to the given linedef private void ReadSidedef(MapSet map, UniversalCollection sc, Linedef ld, bool front, Dictionary <int, Sector> sectorlink, int index) { // Read fields string where = "linedef " + ld.Index + (front ? " front sidedef " : " back sidedef ") + index; int offsetx = GetCollectionEntry <int>(sc, "offsetx", false, 0, where); int offsety = GetCollectionEntry <int>(sc, "offsety", false, 0, where); string thigh = GetCollectionEntry <string>(sc, "texturetop", false, "-", where); string tlow = GetCollectionEntry <string>(sc, "texturebottom", false, "-", where); string tmid = GetCollectionEntry <string>(sc, "texturemiddle", false, "-", where); int sector = GetCollectionEntry <int>(sc, "sector", true, 0, where); // Create sidedef if (sectorlink.ContainsKey(sector)) { Sidedef s = map.CreateSidedef(ld, front, sectorlink[sector]); if (s != null) { s.Update(offsetx, offsety, thigh, tmid, tlow); // Custom fields ReadCustomFields(sc, s, "sidedef"); } } else { General.ErrorLogger.Add(ErrorType.Warning, "Sidedef references invalid sector " + sector + ". Sidedef has been removed."); } }
private static void AddWall(MapSet map, BuildWall data, Linedef ld, bool front, Dictionary <int, BuildSector> sectorlink) { // Create sidedef if (sectorlink.ContainsKey(data.SectorID)) { Sidedef s = map.CreateSidedef(ld, front, sectorlink[data.SectorID].Sector); if (s != null) { s.Update(data); } } else { General.ErrorLogger.Add(ErrorType.Warning, "Wall references invalid sector " + data.SectorID + ". Wall has been removed."); } }
private static void AddSidedef(MapSet map, SidedefData data, Linedef ld, bool front, Dictionary <int, Sector> sectorlink) { // Create sidedef if (sectorlink.ContainsKey(data.SectorID)) { Sidedef s = map.CreateSidedef(ld, front, sectorlink[data.SectorID]); if (s != null) { s.Update(data.OffsetX, data.OffsetY, data.HighTexture, data.MiddleTexture, data.LowTexture, data.Flags); // Add custom fields foreach (KeyValuePair <string, UniValue> group in data.Fields) { s.Fields.Add(group.Key, group.Value); } } } else { General.ErrorLogger.Add(ErrorType.Warning, "Sidedef references invalid sector " + data.SectorID + ". Sidedef 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(); }
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 from WAD file private void ReadLinedefs(MapSet map, int firstindex, Dictionary <int, Vertex> vertexlink, Dictionary <int, Sector> sectorlink) { MemoryStream linedefsmem, sidedefsmem; BinaryReader readline, readside; Lump linedefslump, sidedefslump; int num, numsides, i, offsetx, offsety, v1, v2; int s1, s2, flags, action, tag, sc; Dictionary <string, bool> stringflags; string thigh, tmid, tlow; Linedef l; Sidedef s; // Get the linedefs lump from wad file linedefslump = wad.FindLump("LINEDEFS", firstindex); if (linedefslump == null) { throw new Exception("Could not find required lump LINEDEFS!"); } // Get the sidedefs lump from wad file sidedefslump = wad.FindLump("SIDEDEFS", firstindex); if (sidedefslump == null) { throw new Exception("Could not find required lump SIDEDEFS!"); } // Prepare to read the items linedefsmem = new MemoryStream(linedefslump.Stream.ReadAllBytes()); sidedefsmem = new MemoryStream(sidedefslump.Stream.ReadAllBytes()); num = (int)linedefslump.Stream.Length / 14; numsides = (int)sidedefslump.Stream.Length / 30; readline = new BinaryReader(linedefsmem); readside = new BinaryReader(sidedefsmem); // Read items from the lump // ano - heuristic to detect sidedef compression if (num > numsides) { // ano - set sidedefs to some larger amount than // numsides before resizing back down // because in the case of sidedef compression the // array will have to be resized a lot map.SetCapacity(0, map.Linedefs.Count + num, map.Sidedefs.Count + (num * 2), 0, 0); } else { // ano - + 32 as extra leniency for some amount of sidedef // compression that goes undetected by the prev check // note this wont be resized back down but 32 is a neglible amount map.SetCapacity(0, map.Linedefs.Count + num, map.Sidedefs.Count + num + 32, 0, 0); } for (i = 0; i < num; i++) { // Read properties from stream v1 = readline.ReadUInt16(); v2 = readline.ReadUInt16(); flags = readline.ReadUInt16(); action = readline.ReadUInt16(); tag = readline.ReadUInt16(); s1 = readline.ReadUInt16(); s2 = readline.ReadUInt16(); // Make string flags stringflags = new Dictionary <string, bool>(); 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) { l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); l.Update(stringflags, 0, tag, action, new int[Linedef.NUM_ARGS]); l.UpdateCache(); // Line has a front side? if (s1 != ushort.MaxValue) { // Read front sidedef if ((s1 * 30L) <= (sidedefsmem.Length - 30L)) { sidedefsmem.Seek(s1 * 30, SeekOrigin.Begin); 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 references invalid sidedef " + s1 + ". Sidedef has been removed."); } } // Line has a back side? if (s2 != ushort.MaxValue) { // Read back sidedef if ((s2 * 30L) <= (sidedefsmem.Length - 30L)) { sidedefsmem.Seek(s2 * 30, SeekOrigin.Begin); 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."); } } if (num > numsides) { // ano - resize the arrays back down map.SetCapacity(0, map.Linedefs.Count, map.Sidedefs.Count, 0, 0); } // Done linedefsmem.Dispose(); sidedefsmem.Dispose(); }