public void RoomSpawnStepSpawnInRoom(int chosenRand, int locX, int locY) { Mock <IRandom> testRand = new Mock <IRandom>(MockBehavior.Strict); // choose freetile count Moq.Language.ISetupSequentialResult <int> seq = testRand.SetupSequence(p => p.Next(4)); seq = seq.Returns(chosenRand); Mock <IPlaceableRoomTestContext> mockMap = new Mock <IPlaceableRoomTestContext>(MockBehavior.Strict); mockMap.SetupGet(p => p.Rand).Returns(testRand.Object); // get free tiles var freeLocs = new List <Loc> { new Loc(1, 2), new Loc(3, 4), new Loc(5, 5), new Loc(3, 2), }; mockMap.Setup(p => p.GetFreeTiles(new Rect(10, 20, 30, 40))).Returns(freeLocs); // expect place item mockMap.Setup(p => p.PlaceItem(new Loc(locX, locY), new SpawnableChar('a'))); Mock <IRoomGen> mockRoom = new Mock <IRoomGen>(MockBehavior.Strict); mockRoom.SetupGet(p => p.Draw).Returns(new Rect(10, 20, 30, 40)); var roomPlan = new FloorRoomPlan(mockRoom.Object); Mock <FloorPlan> mockFloor = new Mock <FloorPlan>(MockBehavior.Strict); mockFloor.Setup(p => p.GetRoomHall(new RoomHallIndex(0, false))).Returns(roomPlan); mockMap.SetupGet(p => p.RoomPlan).Returns(mockFloor.Object); var roomSpawner = new Mock <RoomSpawnStep <IPlaceableRoomTestContext, SpawnableChar> >(null) { CallBase = true }; roomSpawner.Object.SpawnInRoom(mockMap.Object, new RoomHallIndex(0, false), new SpawnableChar('a')); // verify the correct placeitem was called mockMap.Verify(p => p.PlaceItem(new Loc(locX, locY), new SpawnableChar('a')), Times.Exactly(1)); }
public static void CompareFloorPlans(TestFloorPlan floorPlan, TestFloorPlan compareFloorPlan) { Assert.That(floorPlan.RoomCount, Is.EqualTo(compareFloorPlan.RoomCount)); for (int ii = 0; ii < floorPlan.RoomCount; ii++) { FloorRoomPlan plan = floorPlan.PublicRooms[ii]; FloorRoomPlan comparePlan = compareFloorPlan.PublicRooms[ii]; Assert.That(plan.RoomGen, Is.EqualTo(comparePlan.RoomGen)); Assert.That(plan.Adjacents, Is.EqualTo(comparePlan.Adjacents)); } Assert.That(floorPlan.HallCount, Is.EqualTo(compareFloorPlan.HallCount)); for (int ii = 0; ii < floorPlan.HallCount; ii++) { FloorHallPlan plan = floorPlan.PublicHalls[ii]; FloorHallPlan comparePlan = compareFloorPlan.PublicHalls[ii]; Assert.That(plan.RoomGen, Is.EqualTo(comparePlan.RoomGen)); Assert.That(plan.Adjacents, Is.EqualTo(comparePlan.Adjacents)); } }
public void PlaceRoomsOnFloorDefault() { // place a line of rooms with one default string[] inGrid = { "A#B#C", ". . .", "0.0.0", }; TestGridFloorPlan gridPlan = TestGridFloorPlan.InitGridToContext(inGrid, 5, 5); { var gen = new TestFloorPlanGen('A') { ProposedSize = new Loc(5, 5) }; gridPlan.PublicArrayRooms[0].RoomGen = gen; } { gridPlan.PublicArrayRooms[1].RoomGen = new RoomGenDefault <IFloorPlanTestContext>(); gridPlan.PublicArrayRooms[1].PreferHall = true; } { var gen = new TestFloorPlanGen('B') { ProposedSize = new Loc(5, 5) }; gridPlan.PublicArrayRooms[2].RoomGen = gen; } gridPlan.PublicHHalls[0][0].SetGen(new TestFloorPlanGen('b')); gridPlan.PublicHHalls[1][0].SetGen(new TestFloorPlanGen('c')); TestFloorPlan compareFloorPlan = TestFloorPlan.InitFloorToContext( gridPlan.Size, new Rect[] { new Rect(0, 0, 5, 5), new Rect(12, 0, 5, 5) }, new Rect[] { new Rect(6, 0, 1, 1), new Rect(5, 0, 1, 5), new Rect(7, 0, 5, 5) }, new Tuple <char, char>[] { Tuple.Create('A', 'b'), Tuple.Create('b', 'a'), Tuple.Create('a', 'c'), Tuple.Create('c', 'B') }); Mock <IRandom> testRand = new Mock <IRandom>(MockBehavior.Strict); testRand.Setup(p => p.Next(It.IsAny <int>())).Returns(0); var floorPlan = new TestFloorPlan(); floorPlan.InitSize(gridPlan.Size); Mock <IFloorPlanTestContext> mockMap = new Mock <IFloorPlanTestContext>(MockBehavior.Strict); mockMap.SetupGet(p => p.Rand).Returns(testRand.Object); mockMap.SetupGet(p => p.RoomPlan).Returns(floorPlan); gridPlan.PlaceRoomsOnFloor(mockMap.Object); // check the rooms Assert.That(floorPlan.RoomCount, Is.EqualTo(compareFloorPlan.RoomCount)); for (int ii = 0; ii < floorPlan.RoomCount; ii++) { FloorRoomPlan plan = floorPlan.PublicRooms[ii]; FloorRoomPlan comparePlan = compareFloorPlan.PublicRooms[ii]; Assert.That(plan.RoomGen, Is.EqualTo(comparePlan.RoomGen)); Assert.That(plan.Adjacents, Is.EqualTo(comparePlan.Adjacents)); } Assert.That(floorPlan.HallCount, Is.EqualTo(compareFloorPlan.HallCount)); for (int ii = 0; ii < floorPlan.HallCount; ii++) { FloorHallPlan plan = floorPlan.PublicHalls[ii]; FloorHallPlan comparePlan = compareFloorPlan.PublicHalls[ii]; if (ii != 0) { Assert.That(plan.RoomGen, Is.EqualTo(comparePlan.RoomGen)); } else { // special case for the default Assert.That(plan.RoomGen, Is.TypeOf <RoomGenDefault <IFloorPlanTestContext> >()); Assert.That(plan.RoomGen.Draw, Is.EqualTo(comparePlan.RoomGen.Draw)); } Assert.That(plan.Adjacents, Is.EqualTo(comparePlan.Adjacents)); } }
public void TransferBorderToAdjacents(int index, bool isHall, int expectedRoom, int expectedHall) { List <Mock <IRoomGen> > roomGenTarget = new List <Mock <IRoomGen> >(); List <Mock <IPermissiveRoomGen> > hallGenTarget = new List <Mock <IPermissiveRoomGen> >(); var floorPlan = new TestFloorPlan(); floorPlan.InitSize(new Loc(22, 14)); for (int ii = 0; ii < 5; ii++) { Mock <IRoomGen> roomGen = new Mock <IRoomGen>(MockBehavior.Strict); roomGen.SetupGet(p => p.Draw).Returns(Rect.Empty); if (ii == 1 || ii == 3) { roomGen.Setup(p => p.ReceiveOpenedBorder(It.IsAny <IRoomGen>(), It.IsAny <Dir4>())); roomGenTarget.Add(roomGen); } var roomPlan = new FloorRoomPlan(roomGen.Object); roomPlan.Adjacents.Add(new RoomHallIndex(1, false)); roomPlan.Adjacents.Add(new RoomHallIndex(3, false)); roomPlan.Adjacents.Add(new RoomHallIndex(1, true)); roomPlan.Adjacents.Add(new RoomHallIndex(3, true)); floorPlan.PublicRooms.Add(roomPlan); } for (int ii = 0; ii < 5; ii++) { Mock <IPermissiveRoomGen> roomGen = new Mock <IPermissiveRoomGen>(MockBehavior.Strict); roomGen.SetupGet(p => p.Draw).Returns(Rect.Empty); if (ii == 1 || ii == 3) { roomGen.Setup(p => p.ReceiveOpenedBorder(It.IsAny <IRoomGen>(), It.IsAny <Dir4>())); hallGenTarget.Add(roomGen); } var roomPlan = new FloorHallPlan(roomGen.Object); roomPlan.Adjacents.Add(new RoomHallIndex(1, false)); roomPlan.Adjacents.Add(new RoomHallIndex(3, false)); roomPlan.Adjacents.Add(new RoomHallIndex(1, true)); roomPlan.Adjacents.Add(new RoomHallIndex(3, true)); floorPlan.PublicHalls.Add(roomPlan); } IRoomGen from = floorPlan.GetRoomHall(new RoomHallIndex(index, isHall)).RoomGen; floorPlan.TransferBorderToAdjacents(new RoomHallIndex(index, isHall)); for (int ii = 0; ii < roomGenTarget.Count; ii++) { if (ii >= roomGenTarget.Count - expectedRoom) { roomGenTarget[ii].Verify(p => p.ReceiveOpenedBorder(from, It.IsAny <Dir4>()), Times.Exactly(1)); } else { roomGenTarget[ii].Verify(p => p.ReceiveOpenedBorder(from, It.IsAny <Dir4>()), Times.Exactly(0)); } } for (int ii = 0; ii < hallGenTarget.Count; ii++) { if (ii >= hallGenTarget.Count - expectedHall) { hallGenTarget[ii].Verify(p => p.ReceiveOpenedBorder(from, It.IsAny <Dir4>()), Times.Exactly(1)); } else { hallGenTarget[ii].Verify(p => p.ReceiveOpenedBorder(from, It.IsAny <Dir4>()), Times.Exactly(0)); } } }
public static ConsoleKey PrintListRoomHalls(IGenContext map, string msg, bool printDebug, bool printViewer) { IFloorPlanGenContext context = map as IFloorPlanGenContext; if (context == null) { return(ConsoleKey.Enter); } StringBuilder str = new StringBuilder(); FloorPlan plan = context.RoomPlan; if (plan == null) { return(ConsoleKey.Enter); } for (int yy = 0; yy < plan.DrawRect.Bottom; yy++) { for (int xx = 0; xx < plan.DrawRect.Right; xx++) { str.Append(' '); } } for (int ii = 0; ii < plan.RoomCount; ii++) { char chosenChar = '@'; //if (ii < 26) chosenChar = (char)('A' + ii % 26); IRoomGen gen = plan.GetRoom(ii); for (int xx = gen.Draw.Left; xx < gen.Draw.Right; xx++) { for (int yy = gen.Draw.Top; yy < gen.Draw.Bottom; yy++) { int index = yy * plan.DrawRect.Right + xx; if (str[index] == ' ') { str[index] = chosenChar; } else { str[index] = '!'; } } } } for (int ii = 0; ii < plan.HallCount; ii++) { char chosenChar = '#'; //if (ii < 26) chosenChar = (char)('a' + ii % 26); IRoomGen gen = plan.GetHall(ii); for (int xx = gen.Draw.Left; xx < gen.Draw.Right; xx++) { for (int yy = gen.Draw.Top; yy < gen.Draw.Bottom; yy++) { int index = yy * plan.DrawRect.Right + xx; if (str[index] == ' ') { str[index] = chosenChar; } else if (str[index] >= 'a' && str[index] <= 'z' || str[index] == '#') { str[index] = '+'; } else { str[index] = '!'; } } } } for (int yy = plan.DrawRect.Bottom - 1; yy > 0; yy--) { str.Insert(plan.DrawRect.Right * yy, '\n'); } string newStr = str.ToString(); if (listDebugString[currentDepth].MapString == newStr) { return(ConsoleKey.Enter); } listDebugString[currentDepth].MapString = newStr; if (printDebug) { Debug.WriteLine(msg); Debug.Print(newStr); } if (printViewer) { SteppingIn = false; Console.Clear(); Console.WriteLine(msg); Loc start = new Loc(Console.CursorLeft, Console.CursorTop); Console.Write(newStr); Loc end = new Loc(Console.CursorLeft, Console.CursorTop + 1); Console.SetCursorPosition(start.X, start.Y); int prevFarthestPrint = end.Y; while (true) { int farthestPrint = end.Y; Loc mapLoc = new Loc(Console.CursorLeft, Console.CursorTop) - start; rewriteLine(farthestPrint, String.Format("X:{0} Y:{1}", mapLoc.X.ToString("D3"), mapLoc.Y.ToString("D3"))); farthestPrint++; for (int ii = 0; ii < plan.RoomCount; ii++) { FloorRoomPlan roomPlan = plan.GetRoomPlan(ii); if (roomPlan.RoomGen.Draw.Contains(mapLoc)) { //stats string roomString = String.Format("Room #{0}: {1}x{2} {3}", ii, roomPlan.RoomGen.Draw.X, roomPlan.RoomGen.Draw.Y, roomPlan.RoomGen.ToString()); rewriteLine(farthestPrint, roomString); farthestPrint++; string componentString = String.Format("Components: {0}", String.Join(", ", roomPlan.Components)); rewriteLine(farthestPrint, componentString); farthestPrint++; //borders StringBuilder lineString = new StringBuilder(" "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Up, xx) ? "^" : " "); } rewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; for (int yy = 0; yy < roomPlan.RoomGen.Draw.Height; yy++) { lineString = new StringBuilder(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Left, yy) ? "<" : " "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append("#"); } lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Right, yy) ? ">" : " "); rewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; } lineString = new StringBuilder(" "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Down, xx) ? "V" : " "); } rewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; } } for (int ii = 0; ii < plan.HallCount; ii++) { FloorHallPlan hallPlan = plan.GetHallPlan(ii); if (hallPlan.RoomGen.Draw.Contains(mapLoc)) { string roomString = String.Format("Hall #{0}: {1}x{2} {3}", ii, hallPlan.RoomGen.Draw.X, hallPlan.RoomGen.Draw.Y, hallPlan.RoomGen.ToString()); rewriteLine(farthestPrint, roomString); farthestPrint++; string componentString = String.Format("Components: {0}", String.Join(", ", hallPlan.Components)); rewriteLine(farthestPrint, componentString); farthestPrint++; } } for (int ii = farthestPrint; ii < prevFarthestPrint; ii++) { clearLine(ii); } prevFarthestPrint = farthestPrint; Console.SetCursorPosition(start.X + mapLoc.X, start.Y + mapLoc.Y); ConsoleKeyInfo key = Console.ReadKey(true); if (key.Key == ConsoleKey.UpArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Max(start.Y, Console.CursorTop - 1)); } else if (key.Key == ConsoleKey.DownArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Min(Console.CursorTop + 1, end.Y - 1)); } else if (key.Key == ConsoleKey.LeftArrow) { Console.SetCursorPosition(Math.Max(start.X, Console.CursorLeft - 1), Console.CursorTop); } else if (key.Key == ConsoleKey.RightArrow) { Console.SetCursorPosition(Math.Min(Console.CursorLeft + 1, end.X - 1), Console.CursorTop); } else { return(key.Key); } } } else { return(ConsoleKey.Enter); } }
public override void Apply(T map) { Grid.LocTest checkBlock = (Loc testLoc) => { return(!map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) || map.HasTileEffect(testLoc)); }; //choose a room to put the chest in //do not choose a room that would cause disconnection of the floor List <int> possibleRooms = new List <int>(); for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++) { FloorRoomPlan testPlan = map.RoomPlan.GetRoomPlan(ii); //if (map.RoomPlan.IsChokePoint(new RoomHallIndex(ii, false))) // continue; if (!BaseRoomFilter.PassesAllFilters(testPlan, this.Filters)) { continue; } //also do not choose a room that contains the end stairs IViewPlaceableGenContext <MapGenExit> exitMap = (IViewPlaceableGenContext <MapGenExit>)map; if (Collision.InBounds(testPlan.RoomGen.Draw, exitMap.GetLoc(0))) { continue; } possibleRooms.Add(ii); } if (possibleRooms.Count == 0) { return; } List <Loc> freeTiles = new List <Loc>(); IRoomGen room = null; while (possibleRooms.Count > 0) { int chosenRoom = map.Rand.Next(possibleRooms.Count); room = map.RoomPlan.GetRoom(possibleRooms[chosenRoom]); //get all places that the chest is eligible freeTiles = Grid.FindTilesInBox(room.Draw.Start, room.Draw.Size, (Loc testLoc) => { if (map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(testLoc) && map.Tiles[testLoc.X][testLoc.Y + 1].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(new Loc(testLoc.X, testLoc.Y + 1)) && !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Panel] && !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Item]) { if (Grid.GetForkDirs(testLoc, checkBlock, checkBlock).Count < 2) { foreach (MapItem item in map.Items) { if (item.TileLoc == testLoc) { return(false); } } foreach (Team team in map.AllyTeams) { foreach (Character testChar in team.EnumerateChars()) { if (testChar.CharLoc == testLoc) { return(false); } } } foreach (Team team in map.MapTeams) { foreach (Character testChar in team.EnumerateChars()) { if (testChar.CharLoc == testLoc) { return(false); } } } return(true); } } return(false); }); if (freeTiles.Count > 0) { break; } possibleRooms.RemoveAt(chosenRoom); } //can't find any free tile in any room, return if (freeTiles.Count == 0) { return; } if (!ItemThemes.CanPick) { return; } //choose which item theme to work with ItemTheme chosenItemTheme = ItemThemes.Pick(map.Rand); //the item spawn list in this class dictates the items available for spawning //it will be queried for items that match the theme selected List <MapItem> chosenItems = chosenItemTheme.GenerateItems(map, Items); if (chosenItems.Count == 0) { return; } int randIndex = map.Rand.Next(freeTiles.Count); Loc loc = freeTiles[randIndex]; EffectTile spawnedChest = new EffectTile(37, true); if (Ambush && MobThemes.CanPick) { spawnedChest.Danger = true; //the mob theme will be selected randomly MobTheme chosenMobTheme = MobThemes.Pick(map.Rand); //the mobs in this class are the ones that would be available when the game wants to spawn things outside of the floor's spawn list //it will be queried for monsters that match the theme provided List <MobSpawn> chosenMobs = chosenMobTheme.GenerateMobs(map, Mobs); MobSpawnState mobSpawn = new MobSpawnState(); foreach (MobSpawn mob in chosenMobs) { MobSpawn copyMob = mob.Copy(); if (map.Rand.Next(ALT_COLOR_ODDS) == 0) { copyMob.BaseForm.Skin = 1; } mobSpawn.Spawns.Add(copyMob); } spawnedChest.TileStates.Set(mobSpawn); } ItemSpawnState itemSpawn = new ItemSpawnState(); itemSpawn.Spawns = chosenItems; spawnedChest.TileStates.Set(itemSpawn); Rect wallBounds = new Rect(room.Draw.X - 1, room.Draw.Y - 1, room.Draw.Size.X + 2, room.Draw.Size.Y + 2); spawnedChest.TileStates.Set(new BoundsState(wallBounds)); ((IPlaceableGenContext <EffectTile>)map).PlaceItem(loc, spawnedChest); map.PostProcGrid[loc.X][loc.Y].Status[(int)PostProcType.Panel] = true; map.PostProcGrid[loc.X][loc.Y].Status[(int)PostProcType.Item] = true; GenContextDebug.DebugProgress("Placed Chest"); }
public static ConsoleKey PrintListRoomHalls(IGenContext map, string msg, bool printDebug, bool printViewer) { if (!(map is IFloorPlanGenContext context)) { return(ConsoleKey.Enter); } var str = new StringBuilder(); FloorPlan plan = context.RoomPlan; if (plan == null) { return(ConsoleKey.Enter); } for (int yy = 0; yy < plan.DrawRect.Bottom; yy++) { for (int xx = 0; xx < plan.DrawRect.Right; xx++) { str.Append(' '); } } for (int ii = 0; ii < plan.RoomCount; ii++) { char chosenChar = (char)('A' + (ii % 26)); IRoomGen gen = plan.GetRoom(ii); for (int xx = gen.Draw.Left; xx < gen.Draw.Right; xx++) { for (int yy = gen.Draw.Top; yy < gen.Draw.Bottom; yy++) { int index = (yy * plan.DrawRect.Right) + xx; if (str[index] == ' ') { str[index] = chosenChar; } else { str[index] = '!'; } } } } for (int ii = 0; ii < plan.HallCount; ii++) { char chosenChar = (char)('a' + (ii % 26)); IRoomGen gen = plan.GetHall(ii); for (int xx = gen.Draw.Left; xx < gen.Draw.Right; xx++) { for (int yy = gen.Draw.Top; yy < gen.Draw.Bottom; yy++) { int index = (yy * plan.DrawRect.Right) + xx; if (str[index] == ' ') { str[index] = chosenChar; } else if ((str[index] >= 'a' && str[index] <= 'z') || str[index] == '#') { str[index] = '+'; } else { str[index] = '!'; } } } } for (int yy = plan.DrawRect.Bottom - 1; yy > 0; yy--) { str.Insert(plan.DrawRect.Right * yy, '\n'); } string newStr = str.ToString(); if (listDebugString[currentDepth].MapString == newStr) { return(ConsoleKey.Enter); } listDebugString[currentDepth].MapString = newStr; if (printDebug) { Debug.WriteLine(msg); Debug.Print(newStr); } if (printViewer) { SteppingIn = false; Console.Clear(); Console.WriteLine(msg); Loc start = new Loc(Console.CursorLeft, Console.CursorTop); Console.Write(newStr); Loc end = new Loc(Console.CursorLeft, Console.CursorTop + 1); Console.SetCursorPosition(start.X, start.Y); int prevFarthestPrint = end.Y; while (true) { int farthestPrint = end.Y; Loc mapLoc = new Loc(Console.CursorLeft, Console.CursorTop) - start; RewriteLine(farthestPrint, $"X:{mapLoc.X:D3} Y:{mapLoc.Y:D3}"); farthestPrint++; for (int ii = 0; ii < plan.RoomCount; ii++) { FloorRoomPlan roomPlan = plan.GetRoomPlan(ii); if (roomPlan.RoomGen.Draw.Contains(mapLoc)) { // stats string roomString = $"Room #{ii}: {roomPlan.RoomGen.Draw.X}x{roomPlan.RoomGen.Draw.Y} {roomPlan.RoomGen}"; if (roomPlan.Immutable) { roomString += " [Immutable]"; } RewriteLine(farthestPrint, roomString); farthestPrint++; // borders var lineString = new StringBuilder(" "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Up, xx) ? "^" : " "); } RewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; for (int yy = 0; yy < roomPlan.RoomGen.Draw.Height; yy++) { lineString = new StringBuilder(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Left, yy) ? "<" : " "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append("#"); } lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Right, yy) ? ">" : " "); RewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; } lineString = new StringBuilder(" "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Down, xx) ? "V" : " "); } RewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; } } for (int ii = 0; ii < plan.HallCount; ii++) { IPermissiveRoomGen gen = plan.GetHall(ii); if (gen.Draw.Contains(mapLoc)) { string roomString = $"Hall #{ii}: {gen.Draw.X}x{gen.Draw.Y} {gen}"; RewriteLine(farthestPrint, roomString); farthestPrint++; } } for (int ii = farthestPrint; ii < prevFarthestPrint; ii++) { ClearLine(ii); } prevFarthestPrint = farthestPrint; Console.SetCursorPosition(start.X + mapLoc.X, start.Y + mapLoc.Y); ConsoleKeyInfo key = Console.ReadKey(true); if (key.Key == ConsoleKey.UpArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Max(start.Y, Console.CursorTop - 1)); } else if (key.Key == ConsoleKey.DownArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Min(Console.CursorTop + 1, end.Y - 1)); } else if (key.Key == ConsoleKey.LeftArrow) { Console.SetCursorPosition(Math.Max(start.X, Console.CursorLeft - 1), Console.CursorTop); } else if (key.Key == ConsoleKey.RightArrow) { Console.SetCursorPosition(Math.Min(Console.CursorLeft + 1, end.X - 1), Console.CursorTop); } else { return(key.Key); } } } else { return(ConsoleKey.Enter); } }
protected override void PlaceBorders(T map, Dictionary <Loc, SealType> sealList) { Rect?bossRect = null; for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++) { FloorRoomPlan plan = map.RoomPlan.GetRoomPlan(ii); if (!BaseRoomFilter.PassesAllFilters(plan, this.BossFilters)) { continue; } bossRect = plan.RoomGen.Draw; break; } //if there's no way to open the door, there cannot be a door; give the player the treasure unguarded if (bossRect == null) { return; } EffectTile bossEffect = null; for (int xx = bossRect.Value.Start.X; xx < bossRect.Value.End.X; xx++) { for (int yy = bossRect.Value.Start.Y; yy < bossRect.Value.End.Y; yy++) { if (map.Tiles[xx][yy].Effect.ID == BossTile) { bossEffect = map.Tiles[xx][yy].Effect; break; } } if (bossEffect != null) { break; } } if (bossEffect == null) { return; } List <Loc> lockList = new List <Loc>(); foreach (Loc loc in sealList.Keys) { switch (sealList[loc]) { case SealType.Blocked: map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy(); break; default: lockList.Add(loc); break; } } foreach (Loc loc in lockList) { map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy(); EffectTile newEffect = new EffectTile(SealedTile, true, loc); ((IPlaceableGenContext <EffectTile>)map).PlaceItem(loc, newEffect); } ResultEventState resultEvent = new ResultEventState(); resultEvent.ResultEvents.Add(new OpenVaultEvent(lockList)); bossEffect.TileStates.Set(resultEvent); }
public override void Apply(T map) { //choose a room to cram all the items in List <int> possibleRooms = new List <int>(); for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++) { FloorRoomPlan testPlan = map.RoomPlan.GetRoomPlan(ii); if (!BaseRoomFilter.PassesAllFilters(testPlan, this.Filters)) { continue; } //also do not choose a room that contains the start or end IViewPlaceableGenContext <MapGenEntrance> entranceMap = map; if (Collision.InBounds(testPlan.RoomGen.Draw, entranceMap.GetLoc(0))) { continue; } IViewPlaceableGenContext <MapGenExit> exitMap = map; if (Collision.InBounds(testPlan.RoomGen.Draw, exitMap.GetLoc(0))) { continue; } possibleRooms.Add(ii); } FloorRoomPlan roomPlan = null; Rect limitRect = Rect.Empty; while (possibleRooms.Count > 0) { int chosenRoom = map.Rand.Next(possibleRooms.Count); roomPlan = map.RoomPlan.GetRoomPlan(possibleRooms[chosenRoom]); bool[][] eligibilityGrid = new bool[roomPlan.RoomGen.Draw.Width][]; for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { eligibilityGrid[xx] = new bool[roomPlan.RoomGen.Draw.Height]; for (int yy = 0; yy < roomPlan.RoomGen.Draw.Height; yy++) { bool eligible = true; Loc testLoc = roomPlan.RoomGen.Draw.Start + new Loc(xx, yy); if (map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(testLoc) && map.Tiles[testLoc.X][testLoc.Y + 1].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(new Loc(testLoc.X, testLoc.Y + 1)) && !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Panel] && !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Item]) { foreach (MapItem item in map.Items) { if (item.TileLoc == testLoc) { eligible = false; break; } } } else { eligible = false; } eligibilityGrid[xx][yy] = eligible; } } List <Rect> candRects = Detection.DetectNLargestRects(eligibilityGrid, 1); if (candRects.Count > 0) { limitRect = new Rect(roomPlan.RoomGen.Draw.Start + candRects[0].Start, candRects[0].Size); if (limitRect.Size.X >= MIN_SHOP_SIZE && limitRect.Size.Y >= MIN_SHOP_SIZE) { break; } } possibleRooms.RemoveAt(chosenRoom); } if (limitRect.Size.X < MIN_SHOP_SIZE || limitRect.Size.Y < MIN_SHOP_SIZE) { return; } //randomly roll an actual rectangle within the saferect bounds: between 3x3 and the limit Loc rectSize = new Loc(map.Rand.Next(MIN_SHOP_SIZE, limitRect.Width + 1), map.Rand.Next(MIN_SHOP_SIZE, limitRect.Height + 1)); Loc rectStart = new Loc(limitRect.X + map.Rand.Next(limitRect.Width - rectSize.X + 1), limitRect.Y + map.Rand.Next(limitRect.Height - rectSize.Y + 1)); Rect safeRect = new Rect(rectStart, rectSize); // place the mat of the shop List <Loc> itemTiles = new List <Loc>(); for (int xx = safeRect.X; xx < safeRect.End.X; xx++) { for (int yy = safeRect.Y; yy < safeRect.End.Y; yy++) { Loc matLoc = new Loc(xx, yy); itemTiles.Add(matLoc); EffectTile effect = new EffectTile(45, true, matLoc); ((IPlaceableGenContext <EffectTile>)map).PlaceItem(matLoc, effect); map.PostProcGrid[matLoc.X][matLoc.Y].Status[(int)PostProcType.Panel] = true; map.PostProcGrid[matLoc.X][matLoc.Y].Status[(int)PostProcType.Item] = true; } } // place the map status for checking shop items and spawning security guards { MapStatus status = new MapStatus(SecurityStatus); status.LoadFromData(); ShopSecurityState securityState = new ShopSecurityState(); for (int ii = 0; ii < Mobs.Count; ii++) { securityState.Security.Add(Mobs.GetSpawn(ii).Copy(), Mobs.GetSpawnRate(ii)); } status.StatusStates.Set(securityState); status.StatusStates.Set(new MapIndexState(Personality)); map.Map.Status.Add(SecurityStatus, status); } // place the mob running the shop { ExplorerTeam newTeam = new ExplorerTeam(); newTeam.SetRank(1); Character shopkeeper = StartMob.Spawn(newTeam, map); Loc randLoc = itemTiles[map.Rand.Next(itemTiles.Count)]; ((IGroupPlaceableGenContext <TeamSpawn>)map).PlaceItems(new TeamSpawn(newTeam, true), new Loc[] { randLoc }); } //choose which item theme to work with ItemTheme chosenItemTheme = ItemThemes.Pick(map.Rand); //the item spawn list in this class dictates the items available for spawning //it will be queried for items that match the theme selected List <MapItem> chosenItems = chosenItemTheme.GenerateItems(map, Items); //place the items for (int ii = 0; ii < chosenItems.Count; ii++) { if (itemTiles.Count > 0) { MapItem item = new MapItem(chosenItems[ii]); int randIndex = map.Rand.Next(itemTiles.Count); ((IPlaceableGenContext <MapItem>)map).PlaceItem(itemTiles[randIndex], item); itemTiles.RemoveAt(randIndex); } } //prevent the room from being chosen for anything else roomPlan.Components.Set(new NoEventRoom()); }
protected override void PlaceBorders(T map, Dictionary <Loc, SealType> sealList) { List <Loc> freeSwitchTiles = new List <Loc>(); for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++) { FloorRoomPlan plan = map.RoomPlan.GetRoomPlan(ii); if (!BaseRoomFilter.PassesAllFilters(plan, this.SwitchFilters)) { continue; } freeSwitchTiles.AddRange(((IPlaceableGenContext <EffectTile>)map).GetFreeTiles(plan.RoomGen.Draw)); } for (int ii = 0; ii < map.RoomPlan.HallCount; ii++) { FloorHallPlan plan = map.RoomPlan.GetHallPlan(ii); if (!BaseRoomFilter.PassesAllFilters(plan, this.SwitchFilters)) { continue; } freeSwitchTiles.AddRange(((IPlaceableGenContext <EffectTile>)map).GetFreeTiles(plan.RoomGen.Draw)); } //if there's no way to open the door, there cannot be a door; give the player the treasure unguarded if (freeSwitchTiles.Count == 0) { return; } List <Loc> lockList = new List <Loc>(); foreach (Loc loc in sealList.Keys) { switch (sealList[loc]) { case SealType.Blocked: map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy(); break; default: lockList.Add(loc); break; } } foreach (Loc loc in lockList) { map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy(); EffectTile newEffect = new EffectTile(SealedTile, true, loc); ((IPlaceableGenContext <EffectTile>)map).PlaceItem(loc, newEffect); } EffectTile switchTile = new EffectTile(SwitchTile, true); if (TimeLimit) { switchTile.Danger = true; } TileListState state = new TileListState(); state.Tiles = lockList; switchTile.TileStates.Set(state); int randIndex = map.Rand.Next(freeSwitchTiles.Count); ((IPlaceableGenContext <EffectTile>)map).PlaceItem(freeSwitchTiles[randIndex], switchTile); }