public static PatternReplaceCount FloorPatternRect(VMArchitecture target, Rectangle rect, ushort dir, ushort pattern, sbyte level) //returns floors covered { PatternReplaceCount floorsCovered = new PatternReplaceCount(true); if (rect.Width == 0 && rect.Height == 0) { //dot mode, just fill a tile. can be a diagonal. if (rect.X < 0 || rect.X >= target.Width || rect.Y < 0 || rect.Y >= target.Width) { return(floorsCovered); } var wall = target.GetWall((short)rect.X, (short)rect.Y, level); if ((wall.Segments & AnyDiag) > 0 && pattern < 65534) { bool side = ((wall.Segments & WallSegments.HorizontalDiag) > 0) ? (dir < 2) : (dir < 1 || dir > 2); if (side) { if (wall.TopLeftStyle != pattern) { floorsCovered.Add(wall.TopLeftStyle); wall.TopLeftStyle = pattern; } } else { if (wall.TopLeftPattern != pattern) { floorsCovered.Add(wall.TopLeftPattern); wall.TopLeftPattern = pattern; } } target.SetWall((short)rect.X, (short)rect.Y, level, wall); } else if ((wall.Segments & AnyDiag) == 0) { var floor = target.GetFloor((short)rect.X, (short)rect.Y, level); if (floor.Pattern != pattern) { var old = floor.Pattern; floor.Pattern = pattern; if (target.SetFloor((short)rect.X, (short)rect.Y, level, floor, false)) { floorsCovered.DAdd(old); } } } return(floorsCovered); } var xEnd = Math.Min(target.Width, rect.X + rect.Width + 1); var yEnd = Math.Min(target.Height, rect.Y + rect.Height + 1); for (int y = Math.Max(0, rect.Y); y < yEnd; y++) { for (int x = Math.Max(0, rect.X); x < xEnd; x++) { var wall = target.GetWall((short)x, (short)y, level); if ((wall.Segments & AnyDiag) > 0) //diagonal floors are stored in walls { if (pattern < 65534) { continue; } if (wall.TopLeftStyle != pattern) { wall.TopLeftStyle = pattern; floorsCovered.Add(wall.TopLeftStyle); } if (wall.TopLeftPattern != pattern) { wall.TopLeftPattern = pattern; floorsCovered.Add(wall.TopLeftPattern); } target.SetWall((short)x, (short)y, level, wall); } else { var floor = target.GetFloor((short)x, (short)y, level); if (floor.Pattern != pattern) { var old = floor.Pattern; floor.Pattern = pattern; if (target.SetFloor((short)x, (short)y, level, floor, false)) { floorsCovered.DAdd(old); } } } } } return(floorsCovered); }
private static PatternReplaceCount SpreadOnto(WallTile[] walls, int x, int y, int inDir, byte[] map, int width, int height, Stack <Point> spread, ushort pattern, bool floorMode) { PatternReplaceCount filled = new PatternReplaceCount(false); var wall = walls[x + y * width]; if ((wall.Segments & WallSegments.HorizontalDiag) > 0 && (wall.TopRightStyle == 1 || floorMode)) { if (inDir < 2) { //bottom (bottom right pattern) if (!floorMode && wall.BottomLeftPattern != pattern) { filled.Add(wall.BottomLeftPattern); wall.BottomLeftPattern = pattern; } map[x + y * width] |= 1; } else { //top (bottom left pattern) if (!floorMode && wall.BottomRightPattern != pattern) { filled.Add(wall.BottomRightPattern); wall.BottomRightPattern = pattern; } map[x + y * width] |= 2; } if (!floorMode) { walls[x + y * width] = wall; } } else if ((wall.Segments & WallSegments.VerticalDiag) > 0 && (wall.TopRightStyle == 1 || floorMode)) { if (inDir > 0 && inDir < 3) { //left if (!floorMode && wall.BottomRightPattern != pattern) { filled.Add(wall.BottomRightPattern); wall.BottomRightPattern = pattern; } map[x + y * width] |= 1; } else { //right if (!floorMode && wall.BottomLeftPattern != pattern) { filled.Add(wall.BottomLeftPattern); wall.BottomLeftPattern = pattern; } map[x + y * width] |= 2; } if (!floorMode) { walls[x + y * width] = wall; } } else { map[x + y * width] = 3; } spread.Push(new Point(x, y)); return(filled); }
/// <summary> /// Fills a room with a certain Floor pattern. Returns floors covered /// </summary> public static PatternReplaceCount FloorPatternFill(VMArchitecture target, Point pos, ushort pattern, sbyte level) //for first floor gen, curRoom should be 1. For floors above, it should be the last genmap result { if (pattern > 65533 || pos.X < 0 || pos.X >= target.Width || pos.Y < 0 || pos.Y >= target.Height) { return(new PatternReplaceCount()); } pos.X = Math.Max(Math.Min(pos.X, target.Width - 1), 0); pos.Y = Math.Max(Math.Min(pos.Y, target.Height - 1), 0); var walls = target.Walls[level - 1]; var width = target.Width; var height = target.Height; PatternReplaceCount floorsCovered = new PatternReplaceCount(true); byte[] Map = new byte[target.Width * target.Height]; //flood fill recursively. Each time choose find and choose the first "0" as the base. //The first recursion (outside) cannot fill into diagonals. var spread = new Stack <Point>(); spread.Push(pos); while (spread.Count > 0) { var item = spread.Pop(); var plusX = (item.X + 1) % width; var minX = (item.X + width - 1) % width; var plusY = (item.Y + 1) % height; var minY = (item.Y + height - 1) % height; var mainWalls = walls[item.X + item.Y * width]; var floor = target.GetFloor((short)item.X, (short)item.Y, level); if ((byte)mainWalls.Segments > 15) { //draw floor onto a diagonal; var wall = walls[item.X + item.Y * width]; byte flags = Map[item.X + item.Y * width]; if (flags == 3) { continue; } if ((mainWalls.Segments & WallSegments.HorizontalDiag) > 0) { flags = (byte)(3 - flags); } if ((flags & 1) == 1 && wall.TopLeftPattern != pattern) { floorsCovered.Add(wall.TopLeftPattern); wall.TopLeftPattern = pattern; } else if ((flags & 2) == 2 && wall.TopLeftStyle != pattern) { floorsCovered.Add(wall.TopLeftStyle); wall.TopLeftStyle = pattern; } walls[item.X + item.Y * width] = wall; continue; //don't spread on diagonals for now } else { //normal tile, draw a floor here. if (floor.Pattern != pattern) { var old = floor.Pattern; floor.Pattern = pattern; if (target.SetFloor((short)item.X, (short)item.Y, level, floor, false)) { floorsCovered.DAdd(old); } } } if (Map[plusX + item.Y * width] < 3 && (mainWalls.Segments & WallSegments.BottomRight) == 0) { SpreadOnto(walls, plusX, item.Y, 0, Map, width, height, spread, pattern, true); } if (Map[minX + item.Y * width] < 3 && (mainWalls.Segments & WallSegments.TopLeft) == 0) { SpreadOnto(walls, minX, item.Y, 2, Map, width, height, spread, pattern, true); } if (Map[item.X + plusY * width] < 3 && (mainWalls.Segments & WallSegments.BottomLeft) == 0) { SpreadOnto(walls, item.X, plusY, 1, Map, width, height, spread, pattern, true); } if (Map[item.X + minY * width] < 3 && (mainWalls.Segments & WallSegments.TopRight) == 0) { SpreadOnto(walls, item.X, minY, 3, Map, width, height, spread, pattern, true); } walls[item.X + item.Y * width] = mainWalls; } return(floorsCovered); }
public static PatternReplaceCount WallPatternDot(VMArchitecture target, Point pos, ushort pattern, int direction, int altDir, sbyte level) { if (pos.X < 0 || pos.X >= target.Width || pos.Y < 0 || pos.Y > target.Height) { return new PatternReplaceCount { Total = -1 } } ; //pattern replace count used a little differently here. cost still stores replaced cost, but total stores replaced direction. PatternReplaceCount replaceCost = new PatternReplaceCount(false); ushort replaced = 0; var wall = target.GetWall((short)pos.X, (short)pos.Y, level); //direction starts lefttop, righttop if ((wall.Segments & WallSegments.HorizontalDiag) > 0 && wall.TopRightStyle == 1) { if (direction < 2) { //bottom (bottom right pattern) replaced = wall.BottomRightPattern; wall.BottomRightPattern = pattern; } else { //top (bottom left pattern) replaced = wall.BottomLeftPattern; wall.BottomLeftPattern = pattern; } target.SetWall((short)pos.X, (short)pos.Y, level, wall); if (replaced == pattern) { return new PatternReplaceCount { Total = -1 } } ; replaceCost.Add(replaced); replaceCost.Total = direction; return(replaceCost); } else if ((wall.Segments & WallSegments.VerticalDiag) > 0 && wall.TopRightStyle == 1) { if (direction > 0 && direction < 3) { //left replaced = wall.BottomLeftPattern; wall.BottomLeftPattern = pattern; } else { //right replaced = wall.BottomRightPattern; wall.BottomRightPattern = pattern; } target.SetWall((short)pos.X, (short)pos.Y, level, wall); if (replaced == pattern) { return new PatternReplaceCount { Total = -1 } } ; replaceCost.Add(replaced); replaceCost.Total = direction; return(replaceCost); } if ((wall.Segments & (WallSegments)(1 << direction)) > 0) { } else if ((wall.Segments & (WallSegments)(1 << altDir)) > 0) { direction = altDir; } else { return(new PatternReplaceCount { Total = -1 }); } if (direction == 0 && wall.TopLeftThick) { replaced = wall.TopLeftPattern; wall.TopLeftPattern = pattern; } else if (direction == 1 && wall.TopRightThick) { replaced = wall.TopRightPattern; wall.TopRightPattern = pattern; } else if (direction == 2 && pos.X < target.Width && target.GetWall((short)(pos.X + 1), (short)pos.Y, level).TopLeftThick) { replaced = wall.BottomRightPattern; wall.BottomRightPattern = pattern; } else if (direction == 3 && pos.Y < target.Height && target.GetWall((short)pos.X, (short)(pos.Y + 1), level).TopRightThick) { replaced = wall.BottomLeftPattern; wall.BottomLeftPattern = pattern; } target.SetWall((short)pos.X, (short)pos.Y, level, wall); if (replaced == pattern) { return new PatternReplaceCount { Total = -1 } } ; replaceCost.Add(replaced); replaceCost.Total = direction; return(replaceCost); }
/// <summary> /// Fills a room with a certain wall pattern. Returns walls covered /// </summary> public static PatternReplaceCount WallPatternFill(VMArchitecture target, Point pos, ushort pattern, sbyte level) //for first floor gen, curRoom should be 1. For floors above, it should be the last genmap result { if (pos.X < 0 || pos.X >= target.Width || pos.Y < 0 || pos.Y >= target.Height) { return(new PatternReplaceCount()); } pos.X = Math.Max(Math.Min(pos.X, target.Width - 1), 0); pos.Y = Math.Max(Math.Min(pos.Y, target.Height - 1), 0); var walls = target.Walls[level - 1]; var width = target.Width; var height = target.Height; PatternReplaceCount wallsCovered = new PatternReplaceCount(false); byte[] Map = new byte[target.Width * target.Height]; //flood fill recursively. Each time choose find and choose the first "0" as the base. //The first recursion (outside) cannot fill into diagonals. var spread = new Stack <Point>(); spread.Push(pos); while (spread.Count > 0) { var item = spread.Pop(); var plusX = (item.X + 1) % width; var minX = (item.X + width - 1) % width; var plusY = (item.Y + 1) % height; var minY = (item.Y + height - 1) % height; var mainWalls = walls[item.X + item.Y * width]; if ((byte)mainWalls.Segments > 15) { continue; //don't spread on diagonals for now } var PXWalls = walls[plusX + item.Y * width]; var PYWalls = walls[item.X + plusY * width]; if (Map[plusX + item.Y * width] < 3 && ((PXWalls.Segments & WallSegments.TopLeft) == 0 || PXWalls.TopLeftStyle != 1)) { wallsCovered += SpreadOnto(walls, plusX, item.Y, 0, Map, width, height, spread, pattern, false); } else { if (mainWalls.BottomRightPattern != pattern && PXWalls.TopLeftThick) { wallsCovered.Add(mainWalls.BottomRightPattern); mainWalls.BottomRightPattern = pattern; } } if (Map[minX + item.Y * width] < 3 && ((mainWalls.Segments & WallSegments.TopLeft) == 0 || mainWalls.TopLeftStyle != 1)) { wallsCovered += SpreadOnto(walls, minX, item.Y, 2, Map, width, height, spread, pattern, false); } else { if (mainWalls.TopLeftPattern != pattern && mainWalls.TopLeftThick) { wallsCovered.Add(mainWalls.TopLeftPattern);; mainWalls.TopLeftPattern = pattern; } } if (Map[item.X + plusY * width] < 3 && ((PYWalls.Segments & WallSegments.TopRight) == 0 || PYWalls.TopRightStyle != 1)) { wallsCovered += SpreadOnto(walls, item.X, plusY, 1, Map, width, height, spread, pattern, false); } else { if (mainWalls.BottomLeftPattern != pattern && PYWalls.TopRightThick) { wallsCovered.Add(mainWalls.BottomLeftPattern); mainWalls.BottomLeftPattern = pattern; } } if (Map[item.X + minY * width] < 3 && ((mainWalls.Segments & WallSegments.TopRight) == 0 || mainWalls.TopRightStyle != 1)) { wallsCovered += SpreadOnto(walls, item.X, minY, 3, Map, width, height, spread, pattern, false); } else { if (mainWalls.TopRightPattern != pattern && mainWalls.TopRightThick) { wallsCovered.Add(mainWalls.TopRightPattern); mainWalls.TopRightPattern = pattern; } } walls[item.X + item.Y * width] = mainWalls; } return(wallsCovered); }
private static PatternReplaceCount SpreadOnto(WallTile[] walls, int x, int y, int inDir, byte[] map, int width, int height, Stack<Point> spread, ushort pattern, bool floorMode) { PatternReplaceCount filled = new PatternReplaceCount(false); var wall = walls[x + y * width]; if ((wall.Segments & WallSegments.HorizontalDiag) > 0 && (wall.TopRightStyle == 1 || floorMode)) { if (inDir < 2) { //bottom (bottom right pattern) if (!floorMode && wall.BottomLeftPattern != pattern) { filled.Add(wall.BottomLeftPattern); wall.BottomLeftPattern = pattern; } map[x + y * width] |= 1; } else { //top (bottom left pattern) if (!floorMode && wall.BottomRightPattern != pattern) { filled.Add(wall.BottomRightPattern); wall.BottomRightPattern = pattern; } map[x + y * width] |= 2; } if (!floorMode) walls[x + y * width] = wall; } else if ((wall.Segments & WallSegments.VerticalDiag) > 0 && (wall.TopRightStyle == 1 || floorMode)) { if (inDir > 0 && inDir < 3) { //left if (!floorMode && wall.BottomRightPattern != pattern) { filled.Add(wall.BottomRightPattern); wall.BottomRightPattern = pattern; } map[x + y * width] |= 1; } else { //right if (!floorMode && wall.BottomLeftPattern != pattern) { filled.Add(wall.BottomLeftPattern); wall.BottomLeftPattern = pattern; } map[x + y * width] |= 2; } if (!floorMode) walls[x + y * width] = wall; } else { map[x + y * width] = 3; } spread.Push(new Point(x, y)); return filled; }
//for first floor gen, curRoom should be 1. For floors above, it should be the last genmap result /// <summary> /// Fills a room with a certain wall pattern. Returns walls covered /// </summary> public static PatternReplaceCount WallPatternFill(VMArchitecture target, Point pos, ushort pattern, sbyte level) { if (pos.X < 0 || pos.X >= target.Width || pos.Y < 0 || pos.Y >= target.Height) return new PatternReplaceCount(); pos.X = Math.Max(Math.Min(pos.X, target.Width-1), 0); pos.Y = Math.Max(Math.Min(pos.Y, target.Height-1), 0); var walls = target.Walls[level-1]; var width = target.Width; var height = target.Height; PatternReplaceCount wallsCovered = new PatternReplaceCount(false); byte[] Map = new byte[target.Width * target.Height]; //flood fill recursively. Each time choose find and choose the first "0" as the base. //The first recursion (outside) cannot fill into diagonals. var spread = new Stack<Point>(); spread.Push(pos); while (spread.Count > 0) { var item = spread.Pop(); var plusX = (item.X + 1) % width; var minX = (item.X + width - 1) % width; var plusY = (item.Y + 1) % height; var minY = (item.Y + height - 1) % height; var mainWalls = walls[item.X + item.Y * width]; if ((byte)mainWalls.Segments > 15) continue; //don't spread on diagonals for now var PXWalls = walls[plusX + item.Y * width]; var PYWalls = walls[item.X + plusY * width]; if (Map[plusX + item.Y * width] < 3 && ((PXWalls.Segments & WallSegments.TopLeft) == 0 || PXWalls.TopLeftStyle != 1)) wallsCovered += SpreadOnto(walls, plusX, item.Y, 0, Map, width, height, spread, pattern, false); else { if (mainWalls.BottomRightPattern != pattern && PXWalls.TopLeftThick) { wallsCovered.Add(mainWalls.BottomRightPattern); mainWalls.BottomRightPattern = pattern; } } if (Map[minX + item.Y * width]<3 && ((mainWalls.Segments & WallSegments.TopLeft) == 0 || mainWalls.TopLeftStyle != 1)) wallsCovered += SpreadOnto(walls, minX, item.Y, 2, Map, width, height, spread, pattern, false); else { if (mainWalls.TopLeftPattern != pattern && mainWalls.TopLeftThick) { wallsCovered.Add(mainWalls.TopLeftPattern); ; mainWalls.TopLeftPattern = pattern; } } if (Map[item.X + plusY * width]<3 && ((PYWalls.Segments & WallSegments.TopRight) == 0 || PYWalls.TopRightStyle != 1)) wallsCovered += SpreadOnto(walls, item.X, plusY, 1, Map, width, height, spread, pattern, false); else { if (mainWalls.BottomLeftPattern != pattern && PYWalls.TopRightThick) { wallsCovered.Add(mainWalls.BottomLeftPattern); mainWalls.BottomLeftPattern = pattern; } } if (Map[item.X + minY * width]<3 && ((mainWalls.Segments & WallSegments.TopRight) == 0 || mainWalls.TopRightStyle != 1)) wallsCovered += SpreadOnto(walls, item.X, minY, 3, Map, width, height, spread, pattern, false); else { if (mainWalls.TopRightPattern != pattern && mainWalls.TopRightThick) { wallsCovered.Add(mainWalls.TopRightPattern); mainWalls.TopRightPattern = pattern; } } walls[item.X + item.Y * width] = mainWalls; } return wallsCovered; }
public static PatternReplaceCount WallPatternDot(VMArchitecture target, Point pos, ushort pattern, int direction, int altDir, sbyte level) { if (pos.X < 0 || pos.X >= target.Width || pos.Y < 0 || pos.Y > target.Height) return new PatternReplaceCount { Total = -1 }; //pattern replace count used a little differently here. cost still stores replaced cost, but total stores replaced direction. PatternReplaceCount replaceCost = new PatternReplaceCount(false); ushort replaced = 0; var wall = target.GetWall((short)pos.X, (short)pos.Y, level); //direction starts lefttop, righttop if ((wall.Segments & WallSegments.HorizontalDiag) > 0 && wall.TopRightStyle == 1) { if (direction < 2) { //bottom (bottom right pattern) replaced = wall.BottomRightPattern; wall.BottomRightPattern = pattern; } else { //top (bottom left pattern) replaced = wall.BottomLeftPattern; wall.BottomLeftPattern = pattern; } target.SetWall((short)pos.X, (short)pos.Y, level, wall); if (replaced == pattern) return new PatternReplaceCount { Total = -1 }; replaceCost.Add(replaced); replaceCost.Total = direction; return replaceCost; } else if ((wall.Segments & WallSegments.VerticalDiag) > 0 && wall.TopRightStyle == 1) { if (direction > 0 && direction < 3) { //left replaced = wall.BottomLeftPattern; wall.BottomLeftPattern = pattern; } else { //right replaced = wall.BottomRightPattern; wall.BottomRightPattern = pattern; } target.SetWall((short)pos.X, (short)pos.Y, level, wall); if (replaced == pattern) return new PatternReplaceCount { Total = -1 }; replaceCost.Add(replaced); replaceCost.Total = direction; return replaceCost; } if ((wall.Segments & (WallSegments)(1 << direction)) > 0) { } else if ((wall.Segments & (WallSegments)(1 << altDir)) > 0) direction = altDir; else { return new PatternReplaceCount { Total = -1 }; } if (direction == 0 && wall.TopLeftThick) { replaced = wall.TopLeftPattern; wall.TopLeftPattern = pattern; } else if (direction == 1 && wall.TopRightThick) { replaced = wall.TopRightPattern; wall.TopRightPattern = pattern; } else if (direction == 2 && pos.X < target.Width && target.GetWall((short)(pos.X + 1), (short)pos.Y, level).TopLeftThick) { replaced = wall.BottomRightPattern; wall.BottomRightPattern = pattern; } else if (direction == 3 && pos.Y < target.Height && target.GetWall((short)pos.X, (short)(pos.Y + 1), level).TopRightThick) { replaced = wall.BottomLeftPattern; wall.BottomLeftPattern = pattern; } target.SetWall((short)pos.X, (short)pos.Y, level, wall); if (replaced == pattern) return new PatternReplaceCount { Total = -1 }; replaceCost.Add(replaced); replaceCost.Total = direction; return replaceCost; }
//returns floors covered public static PatternReplaceCount FloorPatternRect(VMArchitecture target, Rectangle rect, ushort dir, ushort pattern, sbyte level) { PatternReplaceCount floorsCovered = new PatternReplaceCount(true); if (rect.Width == 0 && rect.Height == 0) { //dot mode, just fill a tile. can be a diagonal. if (rect.X < 0 || rect.X >= target.Width || rect.Y < 0 || rect.Y >= target.Width) return floorsCovered; var wall = target.GetWall((short)rect.X, (short)rect.Y, level); if ((wall.Segments & AnyDiag) > 0 && pattern < 65534) { bool side = ((wall.Segments & WallSegments.HorizontalDiag) > 0) ? (dir < 2) : (dir < 1 || dir > 2); if (side) { if (wall.TopLeftStyle != pattern) { floorsCovered.Add(wall.TopLeftStyle); wall.TopLeftStyle = pattern; } } else { if (wall.TopLeftPattern != pattern) { floorsCovered.Add(wall.TopLeftPattern); wall.TopLeftPattern = pattern; } } target.SetWall((short)rect.X, (short)rect.Y, level, wall); } else if ((wall.Segments & AnyDiag) == 0) { var floor = target.GetFloor((short)rect.X, (short)rect.Y, level); if (floor.Pattern != pattern) { var old = floor.Pattern; floor.Pattern = pattern; if (target.SetFloor((short)rect.X, (short)rect.Y, level, floor, false)) floorsCovered.DAdd(old); } } return floorsCovered; } var xEnd = Math.Min(target.Width, rect.X + rect.Width+1); var yEnd = Math.Min(target.Height, rect.Y + rect.Height+1); for (int y = Math.Max(0, rect.Y); y < yEnd; y++) { for (int x = Math.Max(0, rect.X); x < xEnd; x++) { var wall = target.GetWall((short)x, (short)y, level); if ((wall.Segments & AnyDiag) > 0) //diagonal floors are stored in walls { if (pattern < 65534) continue; if (wall.TopLeftStyle != pattern) { wall.TopLeftStyle = pattern; floorsCovered.Add(wall.TopLeftStyle); } if (wall.TopLeftPattern != pattern) { wall.TopLeftPattern = pattern; floorsCovered.Add(wall.TopLeftPattern); } target.SetWall((short)x, (short)y, level, wall); } else { var floor = target.GetFloor((short)x, (short)y, level); if (floor.Pattern != pattern) { var old = floor.Pattern; floor.Pattern = pattern; if (target.SetFloor((short)x, (short)y, level, floor, false)) floorsCovered.DAdd(old); } } } } return floorsCovered; }
//for first floor gen, curRoom should be 1. For floors above, it should be the last genmap result /// <summary> /// Fills a room with a certain Floor pattern. Returns floors covered /// </summary> public static PatternReplaceCount FloorPatternFill(VMArchitecture target, Point pos, ushort pattern, sbyte level) { if (pattern > 65533 || pos.X < 0 || pos.X >= target.Width || pos.Y < 0 || pos.Y >= target.Height) return new PatternReplaceCount(); pos.X = Math.Max(Math.Min(pos.X, target.Width - 1), 0); pos.Y = Math.Max(Math.Min(pos.Y, target.Height - 1), 0); var walls = target.Walls[level-1]; var width = target.Width; var height = target.Height; PatternReplaceCount floorsCovered = new PatternReplaceCount(true); byte[] Map = new byte[target.Width * target.Height]; //flood fill recursively. Each time choose find and choose the first "0" as the base. //The first recursion (outside) cannot fill into diagonals. var spread = new Stack<Point>(); spread.Push(pos); while (spread.Count > 0) { var item = spread.Pop(); var plusX = (item.X + 1) % width; var minX = (item.X + width - 1) % width; var plusY = (item.Y + 1) % height; var minY = (item.Y + height - 1) % height; var mainWalls = walls[item.X + item.Y * width]; var floor = target.GetFloor((short)item.X, (short)item.Y, level); if ((byte)mainWalls.Segments > 15) { //draw floor onto a diagonal; var wall = walls[item.X + item.Y * width]; byte flags = Map[item.X + item.Y * width]; if (flags == 3) continue; if ((mainWalls.Segments & WallSegments.HorizontalDiag) > 0) flags = (byte)(3 - flags); if ((flags & 1) == 1 && wall.TopLeftPattern != pattern) { floorsCovered.Add(wall.TopLeftPattern); wall.TopLeftPattern = pattern; } else if ((flags & 2) == 2 && wall.TopLeftStyle != pattern) { floorsCovered.Add(wall.TopLeftStyle); wall.TopLeftStyle = pattern; } walls[item.X + item.Y * width] = wall; continue; //don't spread on diagonals for now } else { //normal tile, draw a floor here. if (floor.Pattern != pattern) { var old = floor.Pattern; floor.Pattern = pattern; if (target.SetFloor((short)item.X, (short)item.Y, level, floor, false)) floorsCovered.DAdd(old); } } if (Map[plusX + item.Y * width] < 3 && (mainWalls.Segments & WallSegments.BottomRight) == 0) SpreadOnto(walls, plusX, item.Y, 0, Map, width, height, spread, pattern, true); if (Map[minX + item.Y * width] < 3 && (mainWalls.Segments & WallSegments.TopLeft) == 0) SpreadOnto(walls, minX, item.Y, 2, Map, width, height, spread, pattern, true); if (Map[item.X + plusY * width] < 3 && (mainWalls.Segments & WallSegments.BottomLeft) == 0) SpreadOnto(walls, item.X, plusY, 1, Map, width, height, spread, pattern, true); if (Map[item.X + minY * width] < 3 && (mainWalls.Segments & WallSegments.TopRight) == 0) SpreadOnto(walls, item.X, minY, 3, Map, width, height, spread, pattern, true); walls[item.X + item.Y * width] = mainWalls; } return floorsCovered; }