public DoorInfo(TemplatePositioned ownerRoom, int ownerRoomIndex, int doorIndex, RoomTemplate.DoorLocation doorLocation) { OwnerRoom = ownerRoom; DoorIndexInRoom = doorIndex; OwnerRoomIndex = ownerRoomIndex; DoorLocation = doorLocation; }
private static void AddStandardDecorativeFeaturesToRoom(int level, TemplatePositioned positionedRoom, int featuresToPlace, DecorationFeatureDetails.Decoration decorationDetails) { var bridgeRouter = new RoomFilling(positionedRoom.Room); var floorPoints = RoomTemplateUtilities.GetPointsInRoomWithTerrain(positionedRoom.Room, RoomTemplateTerrain.Floor); for (int i = 0; i < featuresToPlace; i++) { var randomPoint = floorPoints.RandomElement(); floorPoints.Remove(randomPoint); if (bridgeRouter.SetSquareUnWalkableIfMaintainsConnectivity(randomPoint)) { var featureLocationInMapCoords = positionedRoom.Location + randomPoint; Game.Dungeon.AddFeatureBlocking(new Features.StandardDecorativeFeature(decorationDetails.representation, decorationDetails.colour), level, featureLocationInMapCoords, true); LogFile.Log.LogEntryDebug("Placing feature in room " + positionedRoom.RoomIndex + " at location " + featureLocationInMapCoords, LogDebugLevel.Medium); } if (floorPoints.Count() == 0) { break; } } }
private void AddNewDoorsToPotentialDoors(TemplatePositioned positionedRoom, int roomIndex) { //Store a reference to each potential door in the room int noDoors = positionedRoom.PotentialDoors.Count(); //var currentDoorLocations = potentialDoors.Select(d => d.MapCoords); for (int i = 0; i < noDoors; i++) { //if (!currentDoorLocations.Contains(positionedRoom.PotentialDoors[i])) potentialDoors.Add(new DoorInfo(positionedRoom, roomIndex, i, RoomTemplateUtilities.GetDoorLocation(positionedRoom.Room, i))); } }
/// <summary> /// Add the terrain to the map, overriding what was there before. /// Use with caution since may break connectivity /// Performs no checking and allows any override /// </summary> /// <param name="templateToAdd"></param> /// <returns></returns> public void UnconditionallyOverridePositionedTemplate(TemplatePositioned templateToAdd) { try { mapCache.MergeArea(templateToAdd.Location, templateToAdd.Room.terrainMap, OverrideTerrain); idCache.MergeArea(templateToAdd.Location, MakeIdArray(templateToAdd), OverrideIds); } catch (ArgumentException e) { throw new ApplicationException("Can't place room: " + e.Message); } }
public void CyclesOnSeparateLevelsCanBeReturned() { var builder = new MapInfoBuilder(); var l1ConnectivityMap = new ConnectivityMap(); //Cycle in level 1 l1ConnectivityMap.AddRoomConnection(1, 2); l1ConnectivityMap.AddRoomConnection(2, 3); l1ConnectivityMap.AddRoomConnection(3, 1); var l1RoomList = new List<TemplatePositioned>(); var room1 = new TemplatePositioned(1, 1, 0, null, 1); l1RoomList.Add(room1); l1RoomList.Add(new TemplatePositioned(1, 1, 0, null, 2)); l1RoomList.Add(new TemplatePositioned(1, 1, 0, null, 3)); var l2ConnectivityMap = new ConnectivityMap(); //Cycle in level 2 l2ConnectivityMap.AddRoomConnection(5, 6); l2ConnectivityMap.AddRoomConnection(6, 7); l2ConnectivityMap.AddRoomConnection(7, 5); var l2RoomList = new List<TemplatePositioned>(); var room5 = new TemplatePositioned(1, 1, 0, null, 5); l2RoomList.Add(room5); l2RoomList.Add(new TemplatePositioned(1, 1, 0, null, 6)); l2RoomList.Add(new TemplatePositioned(1, 1, 0, null, 7)); builder.AddConstructedLevel(0, l1ConnectivityMap, l1RoomList, new Dictionary<Connection, Point>(), 1); builder.AddConstructedLevel(1, l2ConnectivityMap, l2RoomList, new Dictionary<Connection, Point>(), new Connection(3, 5)); var mapInfo = new MapInfo(builder); var cyclesOnLevel0 = mapInfo.GetCyclesOnLevel(0).ToList(); Assert.AreEqual(1, cyclesOnLevel0.Count()); CollectionAssert.AreEquivalent(cyclesOnLevel0[0], new List<Connection>{ new Connection(1, 2), new Connection(2, 3), new Connection(3, 1) }); var cyclesOnLevel1 = mapInfo.GetCyclesOnLevel(1).ToList(); Assert.AreEqual(1, cyclesOnLevel1.Count()); CollectionAssert.AreEquivalent(cyclesOnLevel1[0], new List<Connection>{ new Connection(5, 6), new Connection(6, 7), new Connection(7, 5) }); }
public void PotentialDoorsShouldBeAvailableFromPositionedTemplate() { RoomTemplate room1 = LoadTemplateFromAssemblyFile("DDRogueTest.testdata.vaults.test4doors.room"); TemplatePositioned templatePos1 = new TemplatePositioned(11, 12, 0, room1, 0); //Doors at: (3,0),(0,1),(7,1),(3,3) List <Point> outputList = new List<Point>(); outputList.Add(new Point(14, 12)); outputList.Add(new Point(11, 13)); outputList.Add(new Point(18, 13)); outputList.Add(new Point(14, 15)); List<Point> doorList = templatePos1.PotentialDoors.ToList(); CollectionAssert.AreEqual(doorList, outputList); }
public void AddingOverlappingTemplatesWorksIfOnlyOverlapIsOnWallsAndDoors() { //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.test4doors.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); //Base TemplatePositioned templatePos1 = new TemplatePositioned(0, 0, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); //Overlapping by wall and door only TemplatePositioned templatePos2 = new TemplatePositioned(7, 0, 0, room1, 0); Assert.IsTrue(mapGen.AddPositionedTemplate(templatePos2)); }
public void AddingOverlappingTemplatesWorksIfOnlyOverlapIsOnACorner() { //Completely overlapping rooms cause problems with door removal etc. so they can't be allowed //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testsolid1.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); TemplatePositioned templatePos1 = new TemplatePositioned(0, 0, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); TemplatePositioned templatePos2 = new TemplatePositioned(7, 3, 10, room1, 0); var addResult = mapGen.AddPositionedTemplate(templatePos2); Assert.IsTrue(addResult); }
public int PlaceRoomTemplateAtPosition(RoomTemplate roomTemplate, Point point) { var roomIndex = NextRoomIndex(); var positionedRoom = new TemplatePositioned(point.x, point.y, 0, roomTemplate, roomIndex); templates[roomIndex] = positionedRoom; bool placementSuccess = mapBuilder.AddPositionedTemplate(positionedRoom); if (!placementSuccess) { throw new ApplicationException("Can't place template at position"); } IncreaseNextRoomIndex(); AddNewDoorsToPotentialDoors(positionedRoom, roomIndex); return(roomIndex); }
public bool AddPositionedTemplate(TemplatePositioned templateToAdd) { if (!CanBePlacedWithoutOverlappingOtherTemplates(templateToAdd)) { return(false); } try { mapCache.MergeArea(templateToAdd.Location, templateToAdd.Room.terrainMap, MergeTerrain, CheckNotCompletelyOverlapping); idCache.MergeArea(templateToAdd.Location, MakeIdArray(templateToAdd), MergeIds); return(true); } catch (ArgumentException e) { throw new ApplicationException("Can't place room: " + e.Message); } }
/// <summary> /// Add the terrain to the map, overriding what was there before. /// Use with caution since may break connectivity /// </summary> /// <param name="templateToAdd"></param> /// <returns></returns> public bool OverridePositionedTemplate(TemplatePositioned templateToAdd) { if (!CanBePlacedOverlappingOtherTemplates(templateToAdd)) { return(false); } try { mapCache.MergeArea(templateToAdd.Location, templateToAdd.Room.terrainMap, OverrideFloorTerrain); idCache.MergeArea(templateToAdd.Location, MakeIdArray(templateToAdd), OverrideIds); return(true); } catch (ArgumentException e) { throw new ApplicationException("Can't place room: " + e.Message); } }
private int[,] MakeIdArray(TemplatePositioned template) { var ret = new int[template.Room.terrainMap.GetLength(0), template.Room.terrainMap.GetLength(1)]; for (int i = 0; i < template.Room.terrainMap.GetLength(0); i++) { for (int j = 0; j < template.Room.terrainMap.GetLength(1); j++) { if (template.Room.terrainMap[i, j] != RoomTemplateTerrain.Transparent) { ret[i, j] = template.RoomIndex; } else { ret[i, j] = defaultId; } } } return(ret); }
/// <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 void TestAddTemplateOnTopWorksWithNoExistingTemplates() { //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testsolid1.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); TemplatePositioned templatePos1 = new TemplatePositioned(0, 0, 0, room1, 0); Assert.IsTrue(mapGen.AddPositionedTemplate(templatePos1)); }
public void TerrainAtPointCanBeOverriden() { //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testsolid1.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); TemplatePositioned templatePos1 = new TemplatePositioned(0, 0, 0, room1, 1); mapGen.AddPositionedTemplate(templatePos1); mapGen.AddOverrideTerrain(new Point(0, 0), RoomTemplateTerrain.Floor); Map outputMap = mapGen.MergeTemplatesIntoMap(GetStandardTerrainMapping()); Assert.AreEqual(MapTerrain.Empty, outputMap.mapSquares[0, 0].Terrain); }
public void TemplateCantBeOverlappedUsingOverrideTemplateIfSecondTemplateTriesToReplacesNonFloorTiles() { //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.test4doors.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); Stream overlapFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testoverlap.room"); RoomTemplate room2 = RoomTemplateLoader.LoadTemplateFromFile(overlapFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); //Base TemplatePositioned templatePos1 = new TemplatePositioned(5, 5, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); //Overlap in smaller room TemplatePositioned templatePos2 = new TemplatePositioned(5, 5, 0, room2, 0); Assert.IsFalse(mapGen.OverridePositionedTemplate(templatePos2)); }
public void TemplateCanBeOverlappedUsingUnconditionallyOverrideTemplateWhenTerrainTypesDontMatch() { //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.test4doors.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); Stream overlapFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testoverlap.room"); RoomTemplate room2 = RoomTemplateLoader.LoadTemplateFromFile(overlapFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); //Base TemplatePositioned templatePos1 = new TemplatePositioned(5, 5, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); //Overlap in smaller room TemplatePositioned templatePos2 = new TemplatePositioned(5, 5, 0, room2, 0); mapGen.UnconditionallyOverridePositionedTemplate(templatePos2); Map outputMap = mapGen.MergeTemplatesIntoMap(GetStandardTerrainMapping()); Assert.AreEqual(MapTerrain.Wall, outputMap.mapSquares[3, 0].Terrain); Assert.AreEqual(MapTerrain.ClosedDoor, outputMap.mapSquares[0, 1].Terrain); }
public void TemplateCanBeOverlappedUsingOverrideTemplateIfSecondTemplateOnlyReplacesNonFloorTiles() { //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testalignmentroom3.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); Stream overlapFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testoverlap.room"); RoomTemplate room2 = RoomTemplateLoader.LoadTemplateFromFile(overlapFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); //Base TemplatePositioned templatePos1 = new TemplatePositioned(5, 5, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); //Overlap in smaller room TemplatePositioned templatePos2 = new TemplatePositioned(5, 6, 0, room2, 0); mapGen.OverridePositionedTemplate(templatePos2); Map outputMap = mapGen.MergeTemplatesIntoMap(GetStandardTerrainMapping()); Assert.AreEqual(MapTerrain.ClosedDoor, outputMap.mapSquares[0, 2].Terrain); Assert.AreEqual(MapTerrain.ClosedDoor, outputMap.mapSquares[3, 2].Terrain); }
public bool CanBePlacedWithoutOverlappingOtherTemplates(TemplatePositioned template) { return(mapCache.CheckMergeArea(template.Location, template.Room.terrainMap, MergeTerrain, CheckNotCompletelyOverlapping)); }
private int[,] MakeIdArray(TemplatePositioned template) { var ret = new int[template.Room.terrainMap.GetLength(0), template.Room.terrainMap.GetLength(1)]; for (int i = 0; i < template.Room.terrainMap.GetLength(0); i++) { for (int j = 0; j < template.Room.terrainMap.GetLength(1); j++) { if (template.Room.terrainMap[i, j] != RoomTemplateTerrain.Transparent) ret[i, j] = template.RoomIndex; else ret[i, j] = defaultId; } } return ret; }
/// <summary> /// Add the terrain to the map, overriding what was there before. /// Use with caution since may break connectivity /// </summary> /// <param name="templateToAdd"></param> /// <returns></returns> public bool OverridePositionedTemplate(TemplatePositioned templateToAdd) { if (!CanBePlacedOverlappingOtherTemplates(templateToAdd)) return false; try { mapCache.MergeArea(templateToAdd.Location, templateToAdd.Room.terrainMap, OverrideFloorTerrain); idCache.MergeArea(templateToAdd.Location, MakeIdArray(templateToAdd), OverrideIds); return true; } catch (ArgumentException e) { throw new ApplicationException("Can't place room: " + e.Message); } }
public void TestNonOverlappingSolidRoomsCanBeCheckedToBeAllowedToBePlaced() { //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testsolid1.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); TemplatePositioned templatePos1 = new TemplatePositioned(0, 0, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); TemplatePositioned templatePos2 = new TemplatePositioned(8, 0, 10, room1, 0); Assert.IsTrue(mapGen.CanBePlacedWithoutOverlappingOtherTemplates(templatePos2)); }
/// <summary> /// Join 2 doors with a corridor. They must be on the opposite sides of their parent rooms (for now) /// </summary> public bool JoinDoorsWithCorridor(DoorInfo firstDoor, DoorInfo secondDoor, RoomTemplate corridorTemplate) { try { if (connectionDoors.ContainsKey(new Connection(firstDoor.OwnerRoomIndex, secondDoor.OwnerRoomIndex).Ordered)) { LogFile.Log.LogEntryDebug("No allowing 2nd connection between rooms for now - revisit past 7DRL", LogDebugLevel.High); return(false); } var firstDoorLoc = RoomTemplateUtilities.GetDoorLocation(firstDoor.OwnerRoom.Room, firstDoor.DoorIndexInRoom); var secondDoorLoc = RoomTemplateUtilities.GetDoorLocation(secondDoor.OwnerRoom.Room, secondDoor.DoorIndexInRoom); var firstDoorCoord = firstDoor.MapCoords; var secondDoorCoord = secondDoor.MapCoords; var corridorTermini = RoomTemplateUtilities.CorridorTerminalPointsBetweenDoors(firstDoor.MapCoords, firstDoor.DoorLocation, secondDoor.MapCoords, secondDoor.DoorLocation); bool canDoLSharedCorridor = RoomTemplateUtilities.CanBeConnectedWithLShapedCorridor(firstDoorCoord, firstDoorLoc, secondDoorCoord, secondDoorLoc); bool canDoBendCorridor = RoomTemplateUtilities.CanBeConnectedWithBendCorridor(firstDoorCoord, firstDoorLoc, secondDoorCoord, secondDoorLoc); bool canDoStraightCorridor = RoomTemplateUtilities.CanBeConnectedWithStraightCorridor(firstDoorCoord, firstDoorLoc, secondDoorCoord, secondDoorLoc); bool areAdjacent = corridorTermini.Item1 == secondDoorCoord && corridorTermini.Item2 == firstDoorCoord; bool areOverlapping = firstDoorCoord == secondDoorCoord; if (!canDoLSharedCorridor && !canDoBendCorridor && !canDoStraightCorridor && !areAdjacent && !areOverlapping) { throw new ApplicationException("No corridor available to connect this type of door"); } if (areAdjacent || areOverlapping) { //Add a direct connection in the connectivity graph connectivityMap.AddRoomConnection(firstDoor.OwnerRoomIndex, secondDoor.OwnerRoomIndex); connectionDoors.Add(new Connection(firstDoor.OwnerRoomIndex, secondDoor.OwnerRoomIndex).Ordered, firstDoor); } else { //Create template var horizontal = false; if (firstDoorLoc == RoomTemplate.DoorLocation.Left || firstDoorLoc == RoomTemplate.DoorLocation.Right) { horizontal = true; } int xOffset = corridorTermini.Item2.x - corridorTermini.Item1.x; int yOffset = corridorTermini.Item2.y - corridorTermini.Item1.y; RoomTemplate expandedCorridor; Point corridorTerminus1InTemplate; if (canDoBendCorridor) { int transition = (int)Math.Floor(yOffset / 2.0); if (horizontal == true) { transition = (int)Math.Floor(xOffset / 2.0); } var expandedCorridorAndPoint = RoomTemplateUtilities.ExpandCorridorTemplateBend(xOffset, yOffset, transition, horizontal, corridorTemplate); expandedCorridor = expandedCorridorAndPoint.Item1; corridorTerminus1InTemplate = expandedCorridorAndPoint.Item2; } else if (canDoLSharedCorridor) { var expandedCorridorAndPoint = RoomTemplateUtilities.ExpandCorridorTemplateLShaped(xOffset, yOffset, horizontal, corridorTemplate); expandedCorridor = expandedCorridorAndPoint.Item1; corridorTerminus1InTemplate = expandedCorridorAndPoint.Item2; } else { var offsetToUse = horizontal ? xOffset : yOffset; var expandedCorridorAndPoint = RoomTemplateUtilities.ExpandCorridorTemplateStraight(offsetToUse, horizontal, corridorTemplate); expandedCorridor = expandedCorridorAndPoint.Item1; corridorTerminus1InTemplate = expandedCorridorAndPoint.Item2; } //Place corridor //Match corridor tile to location of door Point topLeftCorridor = corridorTermini.Item1 - corridorTerminus1InTemplate; var corridorRoomIndex = NextRoomIndex(); var positionedCorridor = new TemplatePositioned(topLeftCorridor.x, topLeftCorridor.y, 0, expandedCorridor, corridorRoomIndex); if (!mapBuilder.CanBePlacedWithoutOverlappingOtherTemplates(positionedCorridor)) { return(false); } //Place the corridor mapBuilder.AddPositionedTemplate(positionedCorridor); templates[corridorRoomIndex] = positionedCorridor; IncreaseNextRoomIndex(); //Add connections to the old and new rooms connectivityMap.AddRoomConnection(firstDoor.OwnerRoomIndex, corridorRoomIndex); connectivityMap.AddRoomConnection(corridorRoomIndex, secondDoor.OwnerRoomIndex); connectionDoors.Add(new Connection(firstDoor.OwnerRoomIndex, corridorRoomIndex).Ordered, firstDoor); connectionDoors.Add(new Connection(corridorRoomIndex, secondDoor.OwnerRoomIndex).Ordered, secondDoor); } //Remove both doors from the potential list potentialDoors.Remove(firstDoor); potentialDoors.Remove(secondDoor); return(true); } catch (ApplicationException ex) { LogFile.Log.LogEntryDebug("Failed to join doors: " + ex.Message, LogDebugLevel.Medium); return(false); } }
/// <summary> /// Check placement using the rules for replacing a room /// </summary> /// <param name="template"></param> /// <returns></returns> public bool CanBePlacedOverlappingOtherTemplates(TemplatePositioned template) { return(mapCache.CheckMergeArea(template.Location, template.Room.terrainMap, OverrideFloorTerrain)); }
private MapInfoBuilder GetStandardMapInfoBuilder() { var builder = new MapInfoBuilder(); var l1ConnectivityMap = new ConnectivityMap(); l1ConnectivityMap.AddRoomConnection(1, 2); l1ConnectivityMap.AddRoomConnection(2, 3); var l1RoomList = new List<TemplatePositioned>(); var room1 = new TemplatePositioned(1, 1, 0, null, 1); l1RoomList.Add(room1); l1RoomList.Add(new TemplatePositioned(1, 1, 0, null, 2)); l1RoomList.Add(new TemplatePositioned(1, 1, 0, null, 3)); var l2ConnectivityMap = new ConnectivityMap(); l2ConnectivityMap.AddRoomConnection(5, 6); l2ConnectivityMap.AddRoomConnection(6, 7); var l2RoomList = new List<TemplatePositioned>(); var room5 = new TemplatePositioned(1, 1, 0, null, 5); l2RoomList.Add(room5); l2RoomList.Add(new TemplatePositioned(1, 1, 0, null, 6)); l2RoomList.Add(new TemplatePositioned(1, 1, 0, null, 7)); var l1DoorDict = new Dictionary<Connection, Point>(); l1DoorDict.Add(new Connection(2, 3), new Point(5,5)); var l2DoorDict = new Dictionary<Connection, Point>(); l2DoorDict.Add(new Connection(5, 6), new Point(8, 8)); builder.AddConstructedLevel(0, l1ConnectivityMap, l1RoomList, l1DoorDict, 1); builder.AddConstructedLevel(1, l2ConnectivityMap, l2RoomList, l2DoorDict, new Connection(3, 5)); return builder; }
public void RoomsCanBeRetrievedByIndex() { var newTemplate = new TemplatePositioned(9, 9, 0, null, 100); var mapInfoBuilder = new MapInfoBuilder(); var templateList = new List<TemplatePositioned>(); templateList.Add(newTemplate); var map = new ConnectivityMap(); map.AddRoomConnection(new Connection(100, 101)); mapInfoBuilder.AddConstructedLevel(0, map, templateList, new Dictionary<Connection, Point>(), 100); var mapInfo = new MapInfo(mapInfoBuilder); Assert.AreEqual(new Point(9,9), mapInfo.GetRoom(100).Location); }
/// <summary> /// Place a room template aligned with an existing door. /// Returns Connection(Source = existing room or corridor to new room, Target = new room)) /// </summary> public Connection PlaceRoomTemplateAlignedWithExistingDoor(RoomTemplate roomTemplateToPlace, RoomTemplate corridorTemplate, DoorInfo existingDoor, int newRoomDoorIndex, int distanceApart) { var newRoomIndex = NextRoomIndex(); Point existingDoorLoc = existingDoor.MapCoords; Tuple <TemplatePositioned, Point> newRoomTuple = RoomTemplateUtilities.AlignRoomFacing(roomTemplateToPlace, newRoomIndex, existingDoor.OwnerRoom, newRoomDoorIndex, existingDoor.DoorIndexInRoom, distanceApart); var alignedNewRoom = newRoomTuple.Item1; var alignedDoorLocation = newRoomTuple.Item2; var alignedDoorIndex = alignedNewRoom.PotentialDoors.IndexOf(alignedDoorLocation); var alignedDoor = new DoorInfo(alignedNewRoom, newRoomIndex, alignedDoorIndex, RoomTemplateUtilities.GetDoorLocation(alignedNewRoom.Room, alignedDoorIndex)); //In order to place this successfully, we need to be able to both place the room and a connecting corridor if (!mapBuilder.CanBePlacedWithoutOverlappingOtherTemplates(alignedNewRoom)) { throw new ApplicationException("Room failed to place because overlaps existing room"); } //Increase next room for any corridor we may add IncreaseNextRoomIndex(); TemplatePositioned corridorTemplateConnectingRooms = null; Connection connectionToNewRoom = null; if (distanceApart > 1) { //Need points that are '1-in' from the doors var doorOrientation = RoomTemplateUtilities.GetDoorLocation(existingDoor.OwnerRoom.Room, existingDoor.DoorIndexInRoom); bool isHorizontal = doorOrientation == RoomTemplate.DoorLocation.Left || doorOrientation == RoomTemplate.DoorLocation.Right; var corridorTermini = RoomTemplateUtilities.CorridorTerminalPointsBetweenDoors(existingDoorLoc, existingDoor.DoorLocation, alignedDoorLocation, RoomTemplateUtilities.GetOppositeDoorLocation(existingDoor.DoorLocation)); var corridorIndex = NextRoomIndex(); if (corridorTermini.Item1 == corridorTermini.Item2) { corridorTemplateConnectingRooms = RoomTemplateUtilities.GetTemplateForSingleSpaceCorridor(corridorTermini.Item1, RoomTemplateUtilities.ArePointsOnVerticalLine(corridorTermini.Item1, corridorTermini.Item2), 0, corridorTemplate, corridorIndex); } else { corridorTemplateConnectingRooms = RoomTemplateUtilities.GetTemplateForCorridorBetweenPoints(corridorTermini.Item1, corridorTermini.Item2, 0, corridorTemplate, corridorIndex); } //Implicit guarantee that the corridor won't overlap with the new room we're about to place //(but it may overlap other previously placed rooms or corridors) if (!mapBuilder.CanBePlacedWithoutOverlappingOtherTemplates(corridorTemplateConnectingRooms)) { throw new ApplicationException("Room failed to place because corridor overlaps existing room"); } //Place the corridor mapBuilder.AddPositionedTemplate(corridorTemplateConnectingRooms); templates[corridorIndex] = corridorTemplateConnectingRooms; IncreaseNextRoomIndex(); //Add connections to the old and new rooms connectionToNewRoom = new Connection(corridorIndex, newRoomIndex); connectivityMap.AddRoomConnection(existingDoor.OwnerRoomIndex, corridorIndex); LogFile.Log.LogEntryDebug("Adding connection: " + existingDoor.OwnerRoomIndex + " to " + corridorIndex, LogDebugLevel.Medium); connectivityMap.AddRoomConnection(corridorIndex, newRoomIndex); LogFile.Log.LogEntryDebug("Adding connection: " + corridorIndex + " to " + newRoomIndex, LogDebugLevel.Medium); connectionDoors.Add(new Connection(existingDoor.OwnerRoomIndex, corridorIndex).Ordered, existingDoor); connectionDoors.Add(connectionToNewRoom.Ordered, alignedDoor); } else { //No corridor - a direct connection between the rooms connectionToNewRoom = new Connection(existingDoor.OwnerRoomIndex, newRoomIndex); connectivityMap.AddRoomConnection(existingDoor.OwnerRoomIndex, newRoomIndex); connectionDoors.Add(connectionToNewRoom.Ordered, alignedDoor); LogFile.Log.LogEntryDebug("Adding connection: " + existingDoor.OwnerRoomIndex + " to " + newRoomIndex, LogDebugLevel.Medium); } //Place the room bool successfulPlacement = mapBuilder.AddPositionedTemplate(alignedNewRoom); if (!successfulPlacement) { LogFile.Log.LogEntryDebug("Room failed to place because overlaps own corridor - bug", LogDebugLevel.High); throw new ApplicationException("Room failed to place because overlaps own corridor - bug"); } templates[newRoomIndex] = alignedNewRoom; //Add the new potential doors (excluding the one we are linked on) //Can't find a nice linq alternative int noDoors = alignedNewRoom.PotentialDoors.Count(); for (int i = 0; i < noDoors; i++) { if (alignedNewRoom.PotentialDoors[i] == alignedDoorLocation) { continue; } potentialDoors.Add(new DoorInfo(alignedNewRoom, newRoomIndex, i, RoomTemplateUtilities.GetDoorLocation(alignedNewRoom.Room, i))); } //If successful, remove the candidate door from the list potentialDoors.Remove(existingDoor); return(connectionToNewRoom); }
public void TestOverlappingSolidRoomsReturnFalseWhenTestedForOverlap() { //Completely overlapping rooms cause problems with door removal etc. so they can't be allowed //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testsolid1.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); TemplatePositioned templatePos1 = new TemplatePositioned(0, 0, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); TemplatePositioned templatePos2 = new TemplatePositioned(0, 0, 10, room1, 0); Assert.IsFalse(mapGen.CanBePlacedWithoutOverlappingOtherTemplates(templatePos2)); }
/// <summary> /// Check placement using the rules for replacing a room /// </summary> /// <param name="template"></param> /// <returns></returns> public bool CanBePlacedOverlappingOtherTemplates(TemplatePositioned template) { return mapCache.CheckMergeArea(template.Location, template.Room.terrainMap, OverrideFloorTerrain); }
public void AddingOverlappingTemplatesWorksIfOverlapIsTransparent() { //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testsolid1.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); RoomTemplate corridor1 = LoadTemplateFromFileRogueBasin("RogueBasin.bin.Debug.vaults.corridortemplate3x1.room"); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); //Start TemplatePositioned templatePos1 = new TemplatePositioned(0, 0, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); //End TemplatePositioned templatePos2 = new TemplatePositioned(-10, 20, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos2); //Middle TemplatePositioned templatePos3 = new TemplatePositioned(-8, 30, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos3); //Corridor from start - end that overlaps middle var expandedCorridorAndPoint = RoomTemplateUtilities.ExpandCorridorTemplateLShaped(6, 28, true, corridor1); var positionedCorridor = new TemplatePositioned(-2, 4, 0, expandedCorridorAndPoint.Item1, 3); Assert.IsTrue(mapGen.AddPositionedTemplate(positionedCorridor)); }
public void MapContainsCorrectIdOnTwoNonOverlappingRooms() { //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testsolid1.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); TemplatePositioned templatePos1 = new TemplatePositioned(0, 0, 0, room1, 1); mapGen.AddPositionedTemplate(templatePos1); TemplatePositioned templatePos2 = new TemplatePositioned(8, 0, 10, room1, 2); mapGen.AddPositionedTemplate(templatePos2); Map outputMap = mapGen.MergeTemplatesIntoMap(GetStandardTerrainMapping()); Assert.IsTrue(outputMap.roomIdMap[0, 0] == 1); Assert.IsTrue(outputMap.roomIdMap[8, 0] == 2); }
/// <summary> /// Return a new template with terrain set to all Transparent /// </summary> public static TemplatePositioned TransparentTemplate(TemplatePositioned templateToReplace) { var newTerrain = new RoomTemplateTerrain [templateToReplace.Room.Width, templateToReplace.Room.Height]; for (int i = 0; i < templateToReplace.Room.Width; i++) { for (int j = 0; j < templateToReplace.Room.Height; j++) { newTerrain[i, j] = RoomTemplateTerrain.Transparent; } } return new TemplatePositioned(templateToReplace.X, templateToReplace.Y, templateToReplace.Z, new RoomTemplate(newTerrain), templateToReplace.RoomIndex); }
public void MapContainsDefaultIdForTransparentPartsOfRoom() { //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testtransparent1.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); TemplatePositioned templatePos1 = new TemplatePositioned(0, 0, 0, room1, 12); mapGen.AddPositionedTemplate(templatePos1); Map outputMap = mapGen.MergeTemplatesIntoMap(GetStandardTerrainMapping()); Assert.IsTrue(outputMap.roomIdMap[0, 0] == TemplatedMapBuilder.defaultId); Assert.IsTrue(outputMap.roomIdMap[1, 1] == 12); }
/// <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); }
public void RoomsAtHighXWhichMergeShouldntOverlap() { RoomTemplate room1 = LoadTemplateFromAssemblyFile("DDRogueTest.testdata.vaults.testsolid1.room"); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); TemplatePositioned templatePos1 = new TemplatePositioned(20, 20, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); TemplatePositioned templatePos2 = new TemplatePositioned(21, 21, 1, room1, 0); Assert.IsFalse(mapGen.AddPositionedTemplate(templatePos2)); }
public bool CanBePlacedWithoutOverlappingOtherTemplates(TemplatePositioned template) { return mapCache.CheckMergeArea(template.Location, template.Room.terrainMap, MergeTerrain, CheckNotCompletelyOverlapping); }
public void RoomsCanBePlacedAtPresetZUsingAddPositionedTemplate() { //Load sample template 8x4 RoomTemplate room1 = LoadTemplateFromAssemblyFile("DDRogueTest.testdata.vaults.testsolid1.room"); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); TemplatePositioned templatePos1 = new TemplatePositioned(0, 0, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); TemplatePositioned templatePos2 = new TemplatePositioned(8, 0, 0, room1, 0); Assert.IsTrue(mapGen.AddPositionedTemplate(templatePos2)); }
public void RoomsWithOverlapOnTransparentBoundariesCanBeAdded() { RoomTemplate room1 = LoadTemplateFromAssemblyFile("DDRogueTest.testdata.vaults.testsolid1.room"); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); TemplatePositioned templatePos1 = new TemplatePositioned(0, 0, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); TemplatePositioned templatePos2 = new TemplatePositioned(9, 0, 1, room1, 0); Assert.IsTrue(mapGen.AddPositionedTemplate(templatePos2)); }
public bool AddPositionedTemplate(TemplatePositioned templateToAdd) { if (!CanBePlacedWithoutOverlappingOtherTemplates(templateToAdd)) return false; try { mapCache.MergeArea(templateToAdd.Location, templateToAdd.Room.terrainMap, MergeTerrain, CheckNotCompletelyOverlapping); idCache.MergeArea(templateToAdd.Location, MakeIdArray(templateToAdd), MergeIds); return true; } catch (ArgumentException e) { throw new ApplicationException("Can't place room: " + e.Message); } }
public void TemplateCanBeOverlappedByItself() { //Load sample template 8x4 Assembly _assembly = Assembly.GetExecutingAssembly(); Stream roomFileStream = _assembly.GetManifestResourceStream("DDRogueTest.testdata.vaults.testalignmentroom3.room"); RoomTemplate room1 = RoomTemplateLoader.LoadTemplateFromFile(roomFileStream, StandardTemplateMapping.terrainMapping); TemplatedMapBuilder mapGen = new TemplatedMapBuilder(); //Base TemplatePositioned templatePos1 = new TemplatePositioned(5, 5, 0, room1, 0); mapGen.AddPositionedTemplate(templatePos1); //Overlap the same room as a limit test Assert.IsTrue(mapGen.OverridePositionedTemplate(templatePos1)); }