private void RoofSpread(LotTilePos start, bool[] evaluated, int width, int height, sbyte level, List <RoofRect> result) { var rect = new RoofRect(start.x, start.y, start.x + 8, start.y + 8); var toCtr = new Point(4, 4); while (rect.ExpandDir != -1) { //still have to expand in a direction //order: 0, 2, 1, 3, (xpos,xneg,ypos,yneg) var dir = rect.ExpandDir; var startPt = StartLocation(rect, dir); var testPt = startPt; var inc = advanceByDir[(dir + 1) % 4]; var count = Math.Abs(rect.GetByDir((dir + 1) % 4) - rect.GetByDir((dir + 3) % 4)) / 8; bool canExpand = true; for (int i = 0; i < count; i++) { var tile = new LotTilePos((short)testPt.X, (short)testPt.Y, level); if (!IsRoofable(tile)) { canExpand = false; break; } testPt += inc; } if (!canExpand) { rect.ExpandDir = ExpandOrder[rect.ExpandDir]; } else { //mark as complete - new roof rects cannot START on these tiles.. testPt = startPt; for (int i = 0; i < count; i++) { evaluated[(testPt.X / 8) + (testPt.Y / 8) * width] = true; testPt += inc; } //SPEEDUP: if expansion is within an existing roof rectangle skip to the other end of it var midPt = startPt + new Point(inc.X * count / 2, inc.Y * count / 2) + toCtr; var expandInto = result.FirstOrDefault(x => x.Contains(midPt) && RangeCheck(rect, x, dir)); if (expandInto != null) { rect.SetByDir(dir, expandInto.GetByDir(dir)); } else { //on no detection, expand by 1 rect.SetByDir(dir, rect.GetByDir(dir) + ((dir > 1) ? -8 : 8)); } } } result.Add(rect); }
private bool RangeCheck(RoofRect me, RoofRect into, int dir) { switch (dir % 2) { case 0: return(me.y1 > into.y1 && me.y2 < into.y2); case 1: return(me.x1 > into.x1 && me.x2 < into.x2); } return(false); }
private Point StartLocation(RoofRect rect, int dir) { switch (dir) { case 0: return(new Point(rect.x2, rect.y1)); case 1: return(new Point(rect.x2 - 8, rect.y2)); case 2: return(new Point(rect.x1 - 8, rect.y2 - 8)); case 3: return(new Point(rect.x1, rect.y1 - 8)); } return(new Point()); }
public bool Intersects(RoofRect other) { return(!((other.x1 >= x2 || other.x2 <= x1) || (other.y1 >= y2 || other.y2 <= y1))); }