// This runs the check public override void Run() { BlockMap <BlockEntry> blockmap = BuilderPlug.Me.ErrorCheckForm.BlockMap; int progress = 0; int stepprogress = 0; float maxradius = 0; Dictionary <int, HashSet <int> > processedthingpairs = new Dictionary <int, HashSet <int> >(); //mxd foreach (ThingTypeInfo tti in General.Map.Data.ThingTypes) { if (tti.Radius > maxradius) { maxradius = tti.Radius; } } // Go for all the things foreach (Thing t in General.Map.Map.Things) { ThingTypeInfo info = General.Map.Data.GetThingInfo(t.Type); bool stuck = false; // Check this thing for getting stuck? if ((info.ErrorCheck == ThingTypeInfo.THING_ERROR_INSIDE_STUCK) && (info.Blocking > ThingTypeInfo.THING_BLOCKING_NONE)) { // Make square coordinates from thing float blockingsize = t.Size - ALLOWED_STUCK_DISTANCE; Vector2D lt = new Vector2D(t.Position.x - blockingsize, t.Position.y - blockingsize); Vector2D rb = new Vector2D(t.Position.x + blockingsize, t.Position.y + blockingsize); Vector2D bmlt = new Vector2D(t.Position.x - maxradius, t.Position.y - maxradius); Vector2D bmrb = new Vector2D(t.Position.x + maxradius, t.Position.y + maxradius); // Go for all the lines to see if this thing is stuck List <BlockEntry> blocks = blockmap.GetSquareRange(new RectangleF(bmlt.x, bmlt.y, (bmrb.x - bmlt.x), (bmrb.y - bmlt.y))); Dictionary <Linedef, Linedef> doneblocklines = new Dictionary <Linedef, Linedef>(blocks.Count * 3); foreach (BlockEntry b in blocks) { foreach (Linedef l in b.Lines) { // Only test when sinlge-sided, two-sided + impassable and not already checked if (((l.Back == null) || l.IsFlagSet(General.Map.Config.ImpassableFlag)) && !doneblocklines.ContainsKey(l)) { // Test if line ends are inside the thing if (PointInRect(lt, rb, l.Start.Position) || PointInRect(lt, rb, l.End.Position)) { // Thing stuck in line! stuck = true; SubmitResult(new ResultStuckThingInLine(t, l)); } // Test if the line intersects the square else if (Line2D.GetIntersection(l.Start.Position, l.End.Position, lt.x, lt.y, rb.x, lt.y) || Line2D.GetIntersection(l.Start.Position, l.End.Position, rb.x, lt.y, rb.x, rb.y) || Line2D.GetIntersection(l.Start.Position, l.End.Position, rb.x, rb.y, lt.x, rb.y) || Line2D.GetIntersection(l.Start.Position, l.End.Position, lt.x, rb.y, lt.x, lt.y)) { // Thing stuck in line! stuck = true; SubmitResult(new ResultStuckThingInLine(t, l)); } // Checked doneblocklines.Add(l, l); } } // Check if thing is stuck in other things if (info.Blocking != ThingTypeInfo.THING_BLOCKING_NONE) { foreach (Thing ot in b.Things) { // Don't compare the thing with itself if (t.Index == ot.Index) { continue; } // mxd. Don't compare already processed stuff if (processedthingpairs.ContainsKey(t.Index) && processedthingpairs[t.Index].Contains(ot.Index)) { continue; } // Only check of items that can block if (General.Map.Data.GetThingInfo(ot.Type).Blocking == ThingTypeInfo.THING_BLOCKING_NONE) { continue; } // need to compare the flags if (FlagsOverlap(t, ot) && ThingsOverlap(t, ot)) { stuck = true; SubmitResult(new ResultStuckThingInThing(t, ot)); } //mxd. Prepare collections if (!processedthingpairs.ContainsKey(t.Index)) { processedthingpairs.Add(t.Index, new HashSet <int>()); } if (!processedthingpairs.ContainsKey(ot.Index)) { processedthingpairs.Add(ot.Index, new HashSet <int>()); } //mxd. Add both ways processedthingpairs[t.Index].Add(ot.Index); processedthingpairs[ot.Index].Add(t.Index); } } } } // Check this thing for being outside the map? if (!stuck && info.ErrorCheck >= ThingTypeInfo.THING_ERROR_INSIDE) { // Get the nearest line to see if the thing is outside the map bool outside; Linedef l = General.Map.Map.NearestLinedef(t.Position); if (l.SideOfLine(t.Position) <= 0) { outside = (l.Front == null); } else { outside = (l.Back == null); } // Outside the map? if (outside) { // Make result SubmitResult(new ResultThingOutside(t)); } } // Handle thread interruption try { Thread.Sleep(0); } catch (ThreadInterruptedException) { return; } // We are making progress! if ((++progress / PROGRESS_STEP) > stepprogress) { stepprogress = (progress / PROGRESS_STEP); AddProgress(1); } } }
// This runs the check public override void Run() { BlockMap <BlockEntry> blockmap = BuilderPlug.Me.ErrorCheckForm.BlockMap; int progress = 0; int stepprogress = 0; // Go for all the things foreach (Thing t in General.Map.Map.Things) { ThingTypeInfo info = General.Map.Data.GetThingInfo(t.Type); bool stucked = false; // Check this thing for getting stucked? if ((info.ErrorCheck == ThingTypeInfo.THING_ERROR_INSIDE_STUCKED) && (info.Blocking > ThingTypeInfo.THING_BLOCKING_NONE)) { // Make square coordinates from thing float blockingsize = t.Size - ALLOWED_STUCK_DISTANCE; Vector2D lt = new Vector2D(t.Position.x - blockingsize, t.Position.y - blockingsize); Vector2D rb = new Vector2D(t.Position.x + blockingsize, t.Position.y + blockingsize); // Go for all the lines to see if this thing is stucked List <BlockEntry> blocks = blockmap.GetSquareRange(new RectangleF(lt.x, lt.y, (rb.x - lt.x), (rb.y - lt.y))); Dictionary <Linedef, Linedef> doneblocklines = new Dictionary <Linedef, Linedef>(blocks.Count * 3); foreach (BlockEntry b in blocks) { foreach (Linedef l in b.Lines) { // Only test when sinlge-sided and not already checked if ((l.Back == null) && !doneblocklines.ContainsKey(l)) { // Test if line ends are inside the thing if (PointInRect(lt, rb, l.Start.Position) || PointInRect(lt, rb, l.End.Position)) { // Thing stucked in line! stucked = true; } // Test if the line intersects the square else if (Line2D.GetIntersection(l.Start.Position, l.End.Position, lt.x, lt.y, rb.x, lt.y) || Line2D.GetIntersection(l.Start.Position, l.End.Position, rb.x, lt.y, rb.x, rb.y) || Line2D.GetIntersection(l.Start.Position, l.End.Position, rb.x, rb.y, lt.x, rb.y) || Line2D.GetIntersection(l.Start.Position, l.End.Position, lt.x, rb.y, lt.x, lt.y)) { // Thing stucked in line! stucked = true; } // Checked doneblocklines.Add(l, l); } } } } // Stucked? if (stucked) { // Make result SubmitResult(new ResultStuckedThing(t)); } else { // Check this thing for being outside the map? if (info.ErrorCheck >= ThingTypeInfo.THING_ERROR_INSIDE) { // Get the nearest line to see if the thing is outside the map bool outside = false; Linedef l = General.Map.Map.NearestLinedef(t.Position); if (l.SideOfLine(t.Position) <= 0) { outside = (l.Front == null); } else { outside = (l.Back == null); } // Outside the map? if (outside) { // Make result SubmitResult(new ResultThingOutside(t)); } } } // Handle thread interruption try { Thread.Sleep(0); } catch (ThreadInterruptedException) { return; } // We are making progress! if ((++progress / PROGRESS_STEP) > stepprogress) { stepprogress = (progress / PROGRESS_STEP); AddProgress(1); } } }