public DoorInfo(TemplatePositioned ownerRoom, int ownerRoomIndex, int doorIndex, RoomTemplate.DoorLocation doorLocation) { OwnerRoom = ownerRoom; DoorIndexInRoom = doorIndex; OwnerRoomIndex = ownerRoomIndex; DoorLocation = doorLocation; }
public static List<Point> GetPointsInRoomWithTerrain(RoomTemplate room, RoomTemplateTerrain terrainToFind) { var candidatePoints = new List<Point>(); for (int i = 0; i < room.Width; i++) { for (int j = 0; j < room.Height; j++) { if (room.terrainMap[i, j] == terrainToFind) candidatePoints.Add(new Point(i, j)); } } return candidatePoints; }
public static RoomTemplate.DoorLocation GetOppositeDoorLocation(RoomTemplate.DoorLocation doorLocation) { switch (doorLocation) { case RoomTemplate.DoorLocation.Bottom: return RoomTemplate.DoorLocation.Top; case RoomTemplate.DoorLocation.Top: return RoomTemplate.DoorLocation.Bottom; case RoomTemplate.DoorLocation.Left: return RoomTemplate.DoorLocation.Right; case RoomTemplate.DoorLocation.Right: return RoomTemplate.DoorLocation.Left; } throw new ApplicationException("Unknown door location"); }
public static RoomTemplate.DoorLocation GetDoorLocation(RoomTemplate roomTemplate, int doorIndex) { if (roomTemplate.PotentialDoors.Count <= doorIndex) throw new Exception("Door index higher than available doors"); Point doorLocation = roomTemplate.PotentialDoors[doorIndex].Location; if (doorLocation.y == 0) { return RoomTemplate.DoorLocation.Top; } else if (doorLocation.y == roomTemplate.Height - 1) { return RoomTemplate.DoorLocation.Bottom; } else if (doorLocation.x == 0) { return RoomTemplate.DoorLocation.Left; } else if (doorLocation.x == roomTemplate.Width - 1) { return RoomTemplate.DoorLocation.Right; } else { throw new ApplicationException("Door is not on circumference of room, can't cope"); } }
public static void ExportTemplateToTextFile(RoomTemplate templateToExport, string filename) { try { using (StreamWriter writer = new StreamWriter(filename, false)) { for (int j = 0; j < templateToExport.Height; j++) { StringBuilder mapLine = new StringBuilder(); for (int i = 0; i < templateToExport.Width; i++) { //Defaults char screenChar = RoomTerrainChars[templateToExport.terrainMap[i, j]]; mapLine.Append(screenChar); } writer.WriteLine(mapLine); } } } catch (Exception e) { LogFile.Log.LogEntryDebug("Failed to write file " + e.Message, LogDebugLevel.High); } }
public static Tuple<RoomTemplate, Point> ExpandCorridorTemplateLShaped(int xOffset, int yOffset, bool horizontalFirst, RoomTemplate corridorTemplate) { if (corridorTemplate.Height > 1) throw new ApplicationException("Only corridor templates of height 1 supported"); //I think the code is getting there for #..# but I don't want to put the time in now if (corridorTemplate.Width != 3) throw new ApplicationException("Only corridor templates of width 3 supported"); if(Math.Abs(xOffset) < 1 || Math.Abs(yOffset) < 1) throw new ApplicationException("offset must be at least 1"); int mirroring = 0; RoomTemplateTerrain[,] newRoom; bool useEndPoint = false; if (xOffset < 0 && yOffset < 0) { mirroring = horizontalFirst ? 0 : 2; useEndPoint = horizontalFirst ? true : false; } if (xOffset > 0 && yOffset > 0) { mirroring = horizontalFirst ? 2 : 0; useEndPoint = horizontalFirst ? true : false; } if (xOffset < 0 && yOffset > 0) { mirroring = horizontalFirst ? 3 : 1; useEndPoint = horizontalFirst ? true : false; } if (xOffset > 0 && yOffset < 0) { mirroring = horizontalFirst ? 1 : 3; useEndPoint = horizontalFirst ? true : false; } var roomAndStartPoint = GenerateBaseCorridorLShaped(Math.Abs(xOffset), Math.Abs(yOffset), corridorTemplate); newRoom = roomAndStartPoint.Item1; var startPoint = roomAndStartPoint.Item2; var endPoint = roomAndStartPoint.Item3; RoomTemplate mapToReturn = null; Point startPointMirror = null; Point endPointMirror = null; if (mirroring == 0) { mapToReturn = new RoomTemplate(newRoom, true); startPointMirror = startPoint; endPointMirror = endPoint; } //Horizontal reflection if (mirroring == 1) { var mirrorRoom = new RoomTemplateTerrain[newRoom.GetLength(0), newRoom.GetLength(1)]; for (int i = 0; i < newRoom.GetLength(0); i++) { for (int j = 0; j < newRoom.GetLength(1); j++) { mirrorRoom[newRoom.GetLength(0) - 1 - i, j] = newRoom[i, j]; } } mapToReturn = new RoomTemplate(mirrorRoom, true); startPointMirror = new Point(newRoom.GetLength(0) - 1 - startPoint.x, startPoint.y); endPointMirror = new Point(newRoom.GetLength(0) - 1 - endPoint.x, endPoint.y); } //Y=-X mirror if (mirroring == 2) { var mirrorRoom = new RoomTemplateTerrain[newRoom.GetLength(0), newRoom.GetLength(1)]; for (int i = 0; i < newRoom.GetLength(0); i++) { for (int j = 0; j < newRoom.GetLength(1); j++) { mirrorRoom[i, j] = newRoom[newRoom.GetLength(0) - 1 - i, newRoom.GetLength(1) - 1 - j]; } } mapToReturn = new RoomTemplate(mirrorRoom, true); startPointMirror = new Point(newRoom.GetLength(0) - 1 - startPoint.x, newRoom.GetLength(1) - 1 - startPoint.y); endPointMirror = new Point(newRoom.GetLength(0) - 1 - endPoint.x, newRoom.GetLength(1) - 1 - endPoint.y); } //Vertical reflection if (mirroring == 3) { var mirrorRoom = new RoomTemplateTerrain[newRoom.GetLength(0), newRoom.GetLength(1)]; for (int i = 0; i < newRoom.GetLength(0); i++) { for (int j = 0; j < newRoom.GetLength(1); j++) { mirrorRoom[i, newRoom.GetLength(1) - 1 - j] = newRoom[i, j]; } } mapToReturn = new RoomTemplate(mirrorRoom, true); startPointMirror = new Point(startPoint.x, newRoom.GetLength(1) - 1 - startPoint.y); endPointMirror = new Point(endPoint.x, newRoom.GetLength(1) - 1 - endPoint.y); } if(useEndPoint) return new Tuple<RoomTemplate, Point>(mapToReturn, endPointMirror); else return new Tuple<RoomTemplate, Point>(mapToReturn, startPointMirror); }
/** Stretches a corridor template into a full sized corridor of length. * Template must be n x 1 (1 row deep).*/ public static RoomTemplate ExpandCorridorTemplate(bool switchToHorizontal, int length, RoomTemplate corridorTemplate) { if (corridorTemplate.Height > 1) throw new ApplicationException("Only corridor templates of height 1 supported"); RoomTemplateTerrain[,] newRoom; if (switchToHorizontal) { newRoom = new RoomTemplateTerrain[length, corridorTemplate.Width]; for (int j = 0; j < length; j++) { for (int i = 0; i < corridorTemplate.Width; i++) { newRoom[j, i] = corridorTemplate.terrainMap[i, 0]; } } } else { newRoom = new RoomTemplateTerrain[corridorTemplate.Width, length]; for (int j = 0; j < length; j++) { for (int i = 0; i < corridorTemplate.Width; i++) { newRoom[i, j] = corridorTemplate.terrainMap[i, 0]; } } } return new RoomTemplate(newRoom, true); }
public static bool CanBeConnectedWithStraightCorridor(Point door1Coord, RoomTemplate.DoorLocation door1Loc, Point door2Coord, RoomTemplate.DoorLocation door2Loc) { //Door orientation must be opposite if (door1Loc != GetOppositeDoorLocation(door2Loc)) return false; //Door 2 must be acceptable area for door1 (i.e. correct relative position) if (!DoorLocationIsPossible(door1Loc, door1Coord, door2Coord)) return false; if (door1Loc == RoomTemplate.DoorLocation.Top || door1Loc == RoomTemplate.DoorLocation.Bottom) return ArePointsOnVerticalLine(door1Coord, door2Coord); //if (door1Loc == RoomTemplate.DoorLocation.Left || door1Loc == RoomTemplate.DoorLocation.Right) return ArePointsOnHorizontalLine(door1Coord, door2Coord); }
public static RoomTemplate RotateRoomTemplate(RoomTemplate templateToRotate, TemplateRotation rotationAmount) { return RotateRoomTemplate(templateToRotate, (int)rotationAmount); }
public static RoomTemplate RotateRoomTemplate(RoomTemplate templateToRotate, int ninetyDegreeAntiClockwiseSteps) { RoomTemplateTerrain[,] rotatedTerrain = templateToRotate.terrainMap; for (int i = 0; i < ninetyDegreeAntiClockwiseSteps; i++) { rotatedTerrain = RotateTerrainRight(rotatedTerrain); } return new RoomTemplate(rotatedTerrain); }
public static Point RotateRoomPoint(RoomTemplate templateToRotate, Point pointToRotate, TemplateRotation rotationAmount) { return RotateRoomPoint(templateToRotate, pointToRotate, (int)rotationAmount); }
public static Point RotateRoomPoint(RoomTemplate templateToRotate, Point pointToRotate, int ninetyDegreeAntiClockwiseSteps) { Point rotatedPoint = pointToRotate; for (int i = 0; i < ninetyDegreeAntiClockwiseSteps; i++) { int dimension = i % 2 == 1 ? templateToRotate.Width : templateToRotate.Height; rotatedPoint = RotatePointRight(rotatedPoint, dimension); } return rotatedPoint; }
/** Orient a corridorTemplate for a width 1 / height 1 corridor */ public static TemplatePositioned GetTemplateForSingleSpaceCorridor(Point location, bool corridorRunVertically, int z, RoomTemplate corridorTemplate, int corridorRoomIndex) { if (corridorTemplate.Height > 1) throw new ApplicationException("Corridor template is too long for gap"); bool horizontalSwitchNeeded = !corridorRunVertically; RoomTemplate expandedCorridor = ExpandCorridorTemplate(horizontalSwitchNeeded, 1, corridorTemplate); int centreOfTemplateShortAxis = corridorTemplate.Width / 2; int left = location.x; int top = location.y; //Find the TL for the template to be placed if (horizontalSwitchNeeded) { top -= centreOfTemplateShortAxis; } else { left -= centreOfTemplateShortAxis; } return new TemplatePositioned(left, top, z, expandedCorridor, corridorRoomIndex); }
/** Expand a corridor template (vertically aligned) into a suitable room template */ public static TemplatePositioned GetTemplateForCorridorBetweenPoints(Point point1, Point point2, int z, RoomTemplate corridorTemplate, int corridorRoomIndex) { if (!((point1.x == point2.x) || (point1.y == point2.y))) { throw new ApplicationException("Corridors must be straight"); } bool horizontalSwitchNeeded = false; int length; if (point1.y == point2.y) { horizontalSwitchNeeded = true; length = Math.Abs(point1.x - point2.x) + 1; } else { length = Math.Abs(point1.y - point2.y) + 1; } RoomTemplate expandedCorridor = ExpandCorridorTemplate(horizontalSwitchNeeded, length, corridorTemplate); int centreOfTemplateShortAxis = corridorTemplate.Width / 2; int left = Math.Min(point1.x, point2.x); int top = Math.Min(point1.y, point2.y); //Find the TL for the template to be placed if (horizontalSwitchNeeded) { top -= centreOfTemplateShortAxis; } else { left -= centreOfTemplateShortAxis; } return new TemplatePositioned(left, top, z, expandedCorridor, corridorRoomIndex); }
public static Point GetRandomPointWithTerrain(RoomTemplate room, RoomTemplateTerrain terrainToFind) { var candidatePoints = GetPointsInRoomWithTerrain(room, terrainToFind); return candidatePoints[Game.Random.Next(candidatePoints.Count)]; }
public static bool CanBeConnectedWithBendCorridor(Point door1Coord, RoomTemplate.DoorLocation door1Loc, Point door2Coord, RoomTemplate.DoorLocation door2Loc) { //Door orientation must be opposite if (door1Loc != GetOppositeDoorLocation(door2Loc)) return false; //Door 2 must be acceptable area for door1 if (!DoorLocationIsPossible(door1Loc, door1Coord, door2Coord)) return false; //There must be sufficient length to implement a bend if (door1Loc == RoomTemplate.DoorLocation.Left || door1Loc == RoomTemplate.DoorLocation.Right) { if (Math.Abs(door1Coord.x - door2Coord.x) < 2) return false; } else { if (Math.Abs(door1Coord.y - door2Coord.y) < 2) return false; } //There must be sufficient width to implement a bend if (door1Coord.x == door2Coord.x || door1Coord.y == door2Coord.y) return false; return true; }
public static bool CanBeConnectedWithLShapedCorridor(Point door1Coord, RoomTemplate.DoorLocation door1Loc, Point door2Coord, RoomTemplate.DoorLocation door2Loc) { //Directs and opposites can't connect if(door1Loc == door2Loc) return false; if(door1Loc == GetOppositeDoorLocation(door2Loc)) return false; //Both doors must be in each other's mutual acceptance areas if(!(DoorLocationIsPossible(door1Loc, door1Coord, door2Coord) && DoorLocationIsPossible(door2Loc, door2Coord, door1Coord))) return false; //Offset in x and y must be at least 1 if (door1Coord.x == door2Coord.x || door1Coord.y == door2Coord.y) return false; return true; }
private static bool DoorLocationIsPossible(RoomTemplate.DoorLocation door1Loc, Point door1Coord, Point door2Coord) { if (door1Loc == RoomTemplate.DoorLocation.Top && door2Coord.y > door1Coord.y) return false; if (door1Loc == RoomTemplate.DoorLocation.Bottom && door2Coord.y < door1Coord.y) return false; if (door1Loc == RoomTemplate.DoorLocation.Left && door2Coord.x > door1Coord.x) return false; if (door1Loc == RoomTemplate.DoorLocation.Right && door2Coord.x < door1Coord.x) return false; return true; }
public static Tuple<Point, Point> CorridorTerminalPointsBetweenDoors(Point start, RoomTemplate.DoorLocation startDoorLoc, Point end, RoomTemplate.DoorLocation endDoorLoc) { return new Tuple<Point, Point>(GetPointOutsideDoor(start, startDoorLoc), GetPointOutsideDoor(end, endDoorLoc)); }
public bool Equals(RoomTemplate p) { if ((object)p == null) { return false; } return IsTerrainTheSame(p); }
/// <summary> /// Returns the template and the offset onto the template of the start points (where the offsets are relative to) /// </summary> public static Tuple<RoomTemplate, Point> ExpandCorridorTemplateBend(int xOffset, int yOffset, int lTransition, bool switchToHorizontal, RoomTemplate corridorTemplate) { if (corridorTemplate.Height > 1) throw new ApplicationException("Only corridor templates of height 1 supported"); //I think the code is getting there for #..# but I don't want to put the time in now if (corridorTemplate.Width != 3) throw new ApplicationException("Only corridor templates of width 3 supported"); if (Math.Abs(lTransition) < 1) throw new ApplicationException("transition must be at least 1"); if(Math.Abs(xOffset) < 2 && switchToHorizontal) throw new ApplicationException("Need x-offset of at least 2 for horizontal corridor"); if (Math.Abs(yOffset) < 2 && !switchToHorizontal) throw new ApplicationException("Need y-offset of at least 2 for vertical corridor"); int mirroring = 0; RoomTemplateTerrain[,] newRoom; bool useEndPoint = false; if (xOffset < 0 && yOffset < 0) { useEndPoint = switchToHorizontal ? false : true; } if (xOffset > 0 && yOffset > 0) { useEndPoint = switchToHorizontal ? true : false; } if (xOffset < 0 && yOffset > 0) { useEndPoint = switchToHorizontal ? true : false; } if (xOffset > 0 && yOffset < 0) { useEndPoint = switchToHorizontal ? false : true; } Point startPoint; Point endPoint; if (switchToHorizontal) { if (xOffset < 0 && lTransition > 0 || xOffset > 0 && lTransition < 0) throw new ApplicationException("Transition is not within corridor"); //Horizontal mirroring = 2; int transition = lTransition > 0 ? Math.Abs(xOffset) - lTransition : -lTransition; if (xOffset * yOffset < 0) { mirroring = 3; transition = lTransition > 0 ? lTransition : Math.Abs(xOffset) + lTransition; } var corridorBend = GenerateBaseCorridorBend(yOffset, xOffset, transition, corridorTemplate); newRoom = corridorBend.Item1; startPoint = corridorBend.Item2; endPoint = corridorBend.Item3; } else { if (yOffset < 0 && lTransition > 0 || yOffset > 0 && lTransition < 0) throw new ApplicationException("Transition is not within corridor"); //Vertical int transition = lTransition > 0 ? lTransition : Math.Abs(yOffset) + lTransition; if (xOffset * yOffset < 0) mirroring = 1; var corridorBend = GenerateBaseCorridorBend(xOffset, yOffset, transition, corridorTemplate); newRoom = corridorBend.Item1; startPoint = corridorBend.Item2; endPoint = corridorBend.Item3; } RoomTemplate templateToReturn = null; Point startPointToRet = null; Point endPointToRet = null; if (mirroring == 0) { templateToReturn = new RoomTemplate(newRoom, true); startPointToRet = startPoint; endPointToRet = endPoint; } //Horizontal reflection if (mirroring == 1) { var mirrorRoom = new RoomTemplateTerrain[newRoom.GetLength(0), newRoom.GetLength(1)]; for (int i = 0; i < newRoom.GetLength(0); i++) { for (int j = 0; j < newRoom.GetLength(1); j++) { mirrorRoom[newRoom.GetLength(0) - 1 - i, j] = newRoom[i, j]; } } templateToReturn = new RoomTemplate(mirrorRoom, true); startPointToRet = new Point(newRoom.GetLength(0) - 1 - startPoint.x, startPoint.y); endPointToRet = new Point(newRoom.GetLength(0) - 1 - endPoint.x, endPoint.y); } //X-Y mirror if (mirroring == 2) { var mirrorRoom = new RoomTemplateTerrain[newRoom.GetLength(1), newRoom.GetLength(0)]; for (int i = 0; i < newRoom.GetLength(0); i++) { for (int j = 0; j < newRoom.GetLength(1); j++) { mirrorRoom[newRoom.GetLength(1) - 1 - j, newRoom.GetLength(0) - 1 - i] = newRoom[i, j]; } } templateToReturn = new RoomTemplate(mirrorRoom, true); startPointToRet = new Point(newRoom.GetLength(1) - 1 - startPoint.y, newRoom.GetLength(0) - 1 - startPoint.x); endPointToRet = new Point(newRoom.GetLength(1) - 1 - endPoint.y, newRoom.GetLength(0) - 1 - endPoint.x); } //X-Y mirror, Y reflect if (mirroring == 3) { var mirrorRoom = new RoomTemplateTerrain[newRoom.GetLength(1), newRoom.GetLength(0)]; for (int i = 0; i < newRoom.GetLength(0); i++) { for (int j = 0; j < newRoom.GetLength(1); j++) { mirrorRoom[j, newRoom.GetLength(0) - 1 - i] = newRoom[i, j]; } } templateToReturn = new RoomTemplate(mirrorRoom, true); startPointToRet = new Point(startPoint.y, newRoom.GetLength(0) - 1 - startPoint.x); endPointToRet = new Point(endPoint.y, newRoom.GetLength(0) - 1 - endPoint.x); } if (useEndPoint) return new Tuple<RoomTemplate, Point>(templateToReturn, endPointToRet); else return new Tuple<RoomTemplate, Point>(templateToReturn, startPointToRet); }
/// <summary> /// Returns terrain, start of corridor, end of corridor /// </summary> /// <param name="xOffset"></param> /// <param name="yOffset"></param> /// <param name="corridorTemplate"></param> /// <returns></returns> private static Tuple<RoomTemplateTerrain[, ], Point, Point> GenerateBaseCorridorLShaped(int xOffset, int yOffset, RoomTemplate corridorTemplate) { var absXOffset = Math.Abs(xOffset); var absYOffset = Math.Abs(yOffset); var leftFromCentre = (int)Math.Floor((corridorTemplate.Width - 1) / 2.0); var rightFromCentre = corridorTemplate.Width - 1 - leftFromCentre; var width = absXOffset + leftFromCentre + 1; var height = absYOffset + corridorTemplate.Width - 1; var openSquares = corridorTemplate.Width - 2; var newRoom = new RoomTemplateTerrain[width, height]; //Down left for (int j = 0; j <= yOffset; j++) { for (int i = 0; i < corridorTemplate.Width; i++) { newRoom[i, j] = corridorTemplate.terrainMap[i, 0]; } } //Cap for (int i = 0; i < corridorTemplate.Width; i++) { //Use the outside character (should be solid) newRoom[i, yOffset + 1] = corridorTemplate.terrainMap[0, 0]; } //Overlay rotated cross-corridor. Always prefer open to closed for (int j = 1; j <= absXOffset + 1; j++) { for (int i = 0; i < corridorTemplate.Width; i++) { if (newRoom[j, yOffset - 1 + i] == RoomTemplateTerrain.Transparent || corridorTemplate.terrainMap[i, 0] == RoomTemplateTerrain.Floor) newRoom[j, yOffset - 1 + i] = corridorTemplate.terrainMap[i, 0]; } } return new Tuple<RoomTemplateTerrain[,], Point, Point>(newRoom, new Point(leftFromCentre, 0), new Point(absXOffset + leftFromCentre, absYOffset)); }
public static Tuple<RoomTemplate, Point> ExpandCorridorTemplateStraight(int offset, bool switchToHorizontal, RoomTemplate corridorTemplate) { var length = Math.Abs(offset) + 1; var expandedTemplate = ExpandCorridorTemplate(switchToHorizontal, length, corridorTemplate); Point corridorEndPoint; if (offset > 0) corridorEndPoint = new Point(0, 1); else { if(switchToHorizontal) corridorEndPoint = new Point(-offset, 1); else corridorEndPoint = new Point(1, -offset); } return new Tuple<RoomTemplate, Point>(expandedTemplate, corridorEndPoint); }
private static bool HasWallButNoDoorNeighbours(RoomTemplate room, Point p) { List<Point> adjacentSq = new List<Point>(); adjacentSq.Add(p + new Point(-1, -1)); adjacentSq.Add(p + new Point(-1, 0)); adjacentSq.Add(p + new Point(-1, 1)); adjacentSq.Add(p + new Point(0, -1)); adjacentSq.Add(p + new Point(0, 1)); adjacentSq.Add(p + new Point(1, -1)); adjacentSq.Add(p + new Point(1, 0)); adjacentSq.Add(p + new Point(1, 1)); bool foundWall = false; foreach (var pt in adjacentSq) { if (pt.x < 0 || pt.y < 0 || pt.x >= room.Width || pt.y >= room.Height) continue; if (room.terrainMap[pt.x, pt.y] == RoomTemplateTerrain.Wall) foundWall = true; //This isn't great because it works on the pre-filled in terrain if (room.terrainMap[pt.x, pt.y] == RoomTemplateTerrain.WallWithPossibleDoor) return false; if (room.terrainMap[pt.x, pt.y] == RoomTemplateTerrain.OpenWithPossibleDoor) return false; } if (foundWall) return true; return false; }
public static List<Point> GetBoundaryFloorPointsInRoom(RoomTemplate room) { var candidatePoints = new List<Point>(); for (int i = 0; i < room.Width; i++) { for (int j = 0; j < room.Height; j++) { if(room.terrainMap[i, j] == RoomTemplateTerrain.Floor && HasWallButNoDoorNeighbours(room, new Point(i, j))) candidatePoints.Add(new Point(i,j)); } } return candidatePoints; }
private bool IsTerrainTheSame(RoomTemplate p) { if(p.Width != this.Width) return false; if(p.Height != this.Height) return false; for (int i = 0; i < Width; i++) { for (int j = 0; j < Height; j++) { if (this.terrainMap[i, j] != p.terrainMap[i, j]) return false; } } return true; }
public static List<Point> GetGridFromRoom(RoomTemplate room, int spacing, int jitterSize, double jitterRatio) { List<Point> candidatePoints = new List<Point>(); ; for (int i = 1; i < room.Width - 1; i+= spacing) { for (int j = 1; j < room.Height - 1; j+= spacing) { var doJitter = Game.Random.Next(100) * jitterRatio > 1.0; if (room.terrainMap[i, j] != RoomTemplateTerrain.Floor) continue; Point p = new Point(i, j); if (doJitter) { Point jp = p + new Point(Game.Random.Next(jitterSize + 1), Game.Random.Next(jitterSize + 1)); if (jp.x > 1 && jp.y > 1 && jp.x < room.Width - 2 && jp.y < room.Height - 2) { p = jp; } } candidatePoints.Add(p); } } return candidatePoints; }
/// <summary> /// Align toAlignRoomTemplate so that a straight corridor can be drawn from baseRoom. /// Will rotate toAlignRoomTemplate if required /// </summary> public static Tuple<TemplatePositioned, Point> AlignRoomFacing(RoomTemplate toAlignRoomTemplate, int toAlignRoomIndex, TemplatePositioned baseRoom, int toAlignRoomDoorIndex, int baseRoomDoorIndex, int distanceApart) { Point toAlignDoorLocation = toAlignRoomTemplate.PotentialDoors[toAlignRoomDoorIndex].Location; Point baseDoorLocation = baseRoom.Room.PotentialDoors[baseRoomDoorIndex].Location; RoomTemplate.DoorLocation toAlignDoorLoc = GetDoorLocation(toAlignRoomTemplate, toAlignRoomDoorIndex); RoomTemplate.DoorLocation baseDoorLoc = GetDoorLocation(baseRoom.Room, baseRoomDoorIndex); RoomTemplate rotatedTemplate; Point rotatedtoAlignDoorLocation; //B is toAlignRoomTemplate //A is baseTemplate //Rotate 2 + (Bi - Ai) * 90 degree steps clockwise. int stepsToRotate = 2 + ((int)toAlignDoorLoc - (int)baseDoorLoc); if (stepsToRotate < 0) stepsToRotate += 4; if (stepsToRotate >= 4) stepsToRotate -= 4; rotatedTemplate = RotateRoomTemplate(toAlignRoomTemplate, stepsToRotate); rotatedtoAlignDoorLocation = RotateRoomPoint(toAlignRoomTemplate, toAlignDoorLocation, stepsToRotate); int xOffset = baseDoorLocation.x - rotatedtoAlignDoorLocation.x; int yOffset = baseDoorLocation.y - rotatedtoAlignDoorLocation.y; Point toAlignRoomPosition; if (baseDoorLoc == RoomTemplate.DoorLocation.Bottom) { //Vertical alignment toAlignRoomPosition = new Point(baseRoom.X + xOffset, baseRoom.Y + baseRoom.Room.Height + distanceApart - 1); } else if (baseDoorLoc == RoomTemplate.DoorLocation.Top) { toAlignRoomPosition = new Point(baseRoom.X + xOffset, baseRoom.Y - distanceApart - (rotatedTemplate.Height - 1)); } else if (baseDoorLoc == RoomTemplate.DoorLocation.Right) { //Horizontal alignment toAlignRoomPosition = new Point(baseRoom.X + baseRoom.Room.Width - 1 + distanceApart, baseRoom.Y + yOffset); } else { toAlignRoomPosition = new Point(baseRoom.X - distanceApart - (rotatedTemplate.Width - 1), baseRoom.Y + yOffset); } TemplatePositioned rotatedTemplatePosition = new TemplatePositioned(toAlignRoomPosition.x, toAlignRoomPosition.y, baseRoom.Z + 1, rotatedTemplate, toAlignRoomIndex); Point rotatedDoorLocation = new Point(toAlignRoomPosition.x + rotatedtoAlignDoorLocation.x, toAlignRoomPosition.y + rotatedtoAlignDoorLocation.y); return new Tuple<TemplatePositioned, Point>(rotatedTemplatePosition, rotatedDoorLocation); }
public TemplatePositioned(int x, int y, int z, RoomTemplate room, int roomIndex) { X = x; Y = y; Z = z; Room = room; RoomIndex = roomIndex; }
/// <summary> /// Align toAlignRoomTemplate so that it matches the alignment of baseRoom and the target doors overlap /// </summary> public static Tuple<TemplatePositioned, Point> AlignRoomOverlapping(RoomTemplate toAlignRoomTemplate, int toAlignRoomIndex, TemplatePositioned baseRoom, int toAlignRoomDoorIndex, int baseRoomDoorIndex) { Point toAlignDoorLocation = toAlignRoomTemplate.PotentialDoors[toAlignRoomDoorIndex].Location; Point baseDoorLocation = baseRoom.Room.PotentialDoors[baseRoomDoorIndex].Location; RoomTemplate.DoorLocation toAlignDoorLoc = GetDoorLocation(toAlignRoomTemplate, toAlignRoomDoorIndex); RoomTemplate.DoorLocation baseDoorLoc = GetDoorLocation(baseRoom.Room, baseRoomDoorIndex); RoomTemplate rotatedTemplate; Point rotatedtoAlignDoorLocation; //B is toAlignRoomTemplate //A is baseTemplate //Rotate 2 + (Bi - Ai) * 90 degree steps clockwise. int stepsToRotate = ((int)toAlignDoorLoc - (int)baseDoorLoc); if (stepsToRotate < 0) stepsToRotate += 4; if (stepsToRotate >= 4) stepsToRotate -= 4; rotatedTemplate = RotateRoomTemplate(toAlignRoomTemplate, stepsToRotate); rotatedtoAlignDoorLocation = RotateRoomPoint(toAlignRoomTemplate, toAlignDoorLocation, stepsToRotate); int xOffset = baseDoorLocation.x - rotatedtoAlignDoorLocation.x; int yOffset = baseDoorLocation.y - rotatedtoAlignDoorLocation.y; Point toAlignRoomPosition = new Point(baseRoom.X + xOffset, baseRoom.Y + yOffset); TemplatePositioned rotatedTemplatePosition = new TemplatePositioned(toAlignRoomPosition.x, toAlignRoomPosition.y, baseRoom.Z + 1, rotatedTemplate, toAlignRoomIndex); Point rotatedDoorLocation = new Point(toAlignRoomPosition.x + rotatedtoAlignDoorLocation.x, toAlignRoomPosition.y + rotatedtoAlignDoorLocation.y); return new Tuple<TemplatePositioned, Point>(rotatedTemplatePosition, rotatedDoorLocation); }