public SectorGroup() { sectors = new List<Sector>(); type = SectorGroupType.None; linedefs = new List<Linedef>(); speciallinedefs = new List<Linedef>(); floorheight = ceilingheight = freelinecount = 0; id = _id; _id++; }
public void Update() { type = SectorGroupType.None; floorheight = ceilingheight = freelinecount = 0; linedefs.Clear(); if (sectors.Count == 0) return; // All sectors must have the same floor height to be usable for a floor portal if (sectors.Count(s => s.FloorHeight == sectors[0].FloorHeight) == sectors.Count) type |= SectorGroupType.Floor; // All sectors must have the same ceiling height to be usable for a floor portal if (sectors.Count(s => s.CeilHeight == sectors[0].CeilHeight) == sectors.Count) type |= SectorGroupType.Ceiling; // Cache floor and ceiling heights if ((type & SectorGroupType.Floor) == SectorGroupType.Floor) floorheight = sectors[0].FloorHeight; if ((type & SectorGroupType.Ceiling) == SectorGroupType.Ceiling) ceilingheight = sectors[0].CeilHeight; // Get free lines (line without action) and update the anchor bbanchor = sectors[0].Sidedefs.First().Line.Start.Position; foreach (Sector s in sectors) { foreach (Sidedef sd in s.Sidedefs) { // Free lines if (sd.Line.Action == 0 && sd.Line.Tag == 0) freelinecount++; // Special linedefs if (sd.Line.Action >= 358 && sd.Line.Action <= 361) speciallinedefs.Add(sd.Line); // Anchor if (sd.Line.Start.Position.x < bbanchor.x) bbanchor.x = sd.Line.Start.Position.x; if (sd.Line.End.Position.x < bbanchor.x) bbanchor.x = sd.Line.End.Position.x; if (sd.Line.Start.Position.y > bbanchor.y) bbanchor.y = sd.Line.Start.Position.y; if (sd.Line.End.Position.y > bbanchor.y) bbanchor.y = sd.Line.End.Position.y; } } // Create lines from the geometry outline lines = new List<Line2D>(); List<Line2D> tmplines = new List<Line2D>(); foreach (Sector s in sectors) { foreach (Sidedef sd in s.Sidedefs) { if (!(sectors.Contains(sd.Sector) && (sd.Other != null && sectors.Contains(sd.Other.Sector))) || sd.Other == null) if(!linedefs.Contains(sd.Line)) linedefs.Add(sd.Line); } } // Create lines from linedefs, with a normalized angle between 0° and 180° (in radians) foreach (Linedef ld in linedefs) { if (ld.Angle <= Math.PI) tmplines.Add(new Line2D(ld.Start.Position, ld.End.Position)); else tmplines.Add(new Line2D(ld.End.Position, ld.Start.Position)); } // Merge lines into bigger lines if possible lines.Add(tmplines[0]); tmplines.RemoveAt(0); while (tmplines.Count > 0) { // Current line Line2D cline = lines[lines.Count-1]; // Get all lines with the same angle as the current line and the start position is the end position of the current line List<Line2D> possiblelines = tmplines.Where(l => l.GetAngle() == cline.GetAngle() && l.v1 == cline.v2).ToList(); if (possiblelines.Count > 0) { lines[lines.Count - 1] = new Line2D(cline.v1, possiblelines[0].v2); tmplines.Remove(possiblelines[0]); } else { // Get all lines with the same angle as the current line and the end position is the start position of the current line possiblelines = tmplines.Where(l => l.GetAngle() == cline.GetAngle() && l.v2 == cline.v1).ToList(); if (possiblelines.Count > 0) { lines[lines.Count - 1] = new Line2D(possiblelines[0].v1, cline.v2); tmplines.Remove(possiblelines[0]); } else { lines.Add(tmplines[0]); tmplines.Remove(tmplines[0]); } } } }