public static bool CatacombsEntranceGenerator(NewLevelGen_Room room, Tile[,] roomContents, out IntVector2 stairsLoc) { stairsLoc = null; bool success = true; if (room.Size.X > 10 || room.Size.Y > 10) { return(false); } while (room.Exits.Count > 1) { roomContents[room.Exits[0].X - room.TopLeftCorner.X, room.Exits[0].Y - room.TopLeftCorner.Y].SetFeature(Tile_SimpleFeatureType.STONE_WALL); room.Exits.RemoveAt(0); } for (int i = 1; i < room.Size.X - 1; i++) { for (int k = 1; k < room.Size.Y - 1; k++) { roomContents[i, k].SetFeature(Tile_SimpleFeatureType.FLOOR); } } stairsLoc = roomContents[room.Size.X / 2, room.Size.Y / 2].Position; roomContents[room.Size.X / 2, room.Size.Y / 2].SetFeature(Tile_SimpleFeatureType.STAIRS_SPECIAL); return(success); }
public void ResetGenerator() { _map = new Tile[WIDTH, HEIGHT]; _monsters = new List <ActorData>(); _items = new List <ItemData>(); _startRoom = null; _endRoom = null; _upStairs = null; _downStairs = null; _rooms = new List <NewLevelGen_Room>(); _roomsToBeUsed = new List <NewLevelGen_Room>(); _roomAdjacencies = new List <Tuple <NewLevelGen_Room, NewLevelGen_Room, int> >(); _adjacenciesToBeUsed = new List <Tuple <NewLevelGen_Room, NewLevelGen_Room, int> >(); _floods = new List <IntVector2>(); InitMapWithTileType(Tile_SimpleFeatureType.STONE_WALL); CreateRooms(); _mergeRoomsIterations = 0; _branchRoomsIterations = 0; _digCavesIterations = 0; _makeLakesIterations = 0; _monsterPointsForLevel = _depth * 15; _monsterPointsUsed = 0; _currentStep = 0; _finished = false; }
private void CreateRooms() { int currentRoomListIndex = 0; for (int i = 0; i < (WIDTH - 1) / (_roomSize.X - 1); i++) { for (int k = 0; k < (HEIGHT - 1) / (_roomSize.Y - 1); k++) { NewLevelGen_Room rm = new NewLevelGen_Room(); rm.TopLeftCorner = new IntVector2(i * (_roomSize.X - 1), k * (_roomSize.Y - 1)); rm.Size = new IntVector2(_roomSize); _rooms.Add(rm); //Add adjacencies if (k > 0) { AddAdjacencyBetweenRooms(_rooms[currentRoomListIndex - 1], rm); } if (i > 0) { AddAdjacencyBetweenRooms(_rooms[currentRoomListIndex - HEIGHT / (_roomSize.X - 1)], rm); } currentRoomListIndex++; } } }
private bool MakeCatacombsStairsRoom() { bool success = false; int numOfTries = 0; while (!success && numOfTries < 10) { //Choose a room NewLevelGen_Room candidateRoom = _rooms[Utility.random.Next(_rooms.Count)]; //Copy the map Tile[,] mapCopy = new Tile[WIDTH, HEIGHT]; for (int i = 0; i < WIDTH; i++) { for (int k = 0; k < HEIGHT; k++) { mapCopy[i, k] = _map[i, k].Copy(); } } //Reference this map in a smaller map of the room, which will be passed to the generator Tile[,] roomMap = new Tile[candidateRoom.Size.X, candidateRoom.Size.Y]; for (int i = 0; i < candidateRoom.Size.X; i++) { for (int k = 0; k < candidateRoom.Size.Y; k++) { roomMap[i, k] = mapCopy[i + candidateRoom.TopLeftCorner.X, k + candidateRoom.TopLeftCorner.Y]; } } //Give this to a random generator //TODO: pick a generator in some sort of logical way IntVector2 stairsLoc; bool genSuccess = NewLevelGen_SpecialRoomGenerator.CatacombsEntranceGenerator(candidateRoom, roomMap, out stairsLoc); //Check for connectability List <IntVector2> connectivityResult = GetPathBetweenTiles(mapCopy, _upStairs, _downStairs); if (genSuccess && connectivityResult != null) { connectivityResult = GetPathBetweenTiles(mapCopy, _upStairs, stairsLoc); } if (genSuccess && connectivityResult != null) { success = true; _map = mapCopy; _specialStairs = stairsLoc; } numOfTries++; } return(success); }
private void RemoveRoomAndAdjacencies(NewLevelGen_Room room) { List <Tuple <NewLevelGen_Room, NewLevelGen_Room, int> > adjs = GetAdjacenciesForRoom(room); foreach (Tuple <NewLevelGen_Room, NewLevelGen_Room, int> adj in adjs) { _roomAdjacencies.Remove(adj); } _rooms.Remove(room); }
private void ChooseStartAndEndRooms() { _startRoom = _rooms[Utility.random.Next(_rooms.Count)]; _endRoom = _rooms[Utility.random.Next(_rooms.Count)]; if (_startRoom.Equals(_endRoom)) { ChooseStartAndEndRooms(); } if (GetAdjacentRooms(_startRoom).Contains(_endRoom)) { ChooseStartAndEndRooms(); } }
private bool DoesRoomContainPosition(NewLevelGen_Room room, IntVector2 position) { bool result = true; if (position.X < room.TopLeftCorner.X || position.X >= room.TopLeftCorner.X + room.Size.X) { result = false; } if (position.Y < room.TopLeftCorner.Y || position.Y >= room.TopLeftCorner.Y + room.Size.Y) { result = false; } return(result); }
private List <IntVector2> GetBoundaryBetweenRooms(NewLevelGen_Room roomA, NewLevelGen_Room roomB) { List <IntVector2> results = new List <IntVector2>(); List <IntVector2> roomAEdges = roomA.GetEdges(); foreach (IntVector2 position in roomAEdges) { if (DoesRoomContainPosition(roomB, position)) { results.Add(position); } } return(results); }
private bool PlaceMonster() { bool couldPlaceMonster = false; List <MonsterGenInfo> viableMonsters = GetViableMonsters(_depth, _monsterPointsForLevel - _monsterPointsUsed); if (viableMonsters.Count == 0) { return(false); } int tries = 0; while (!couldPlaceMonster && tries < 10) { //Select a random room int roomToTryIndex = Utility.random.Next(_rooms.Count); NewLevelGen_Room roomToTry = _rooms[roomToTryIndex]; //Get a random position in the room int xPos = roomToTry.TopLeftCorner.X; xPos += Utility.random.Next(1, roomToTry.Size.X / 2); xPos += Utility.random.Next(1, roomToTry.Size.X / 2); int yPos = roomToTry.TopLeftCorner.Y; yPos += Utility.random.Next(1, roomToTry.Size.Y / 2); yPos += Utility.random.Next(1, roomToTry.Size.Y / 2); if (!_map[xPos, yPos].ObstructsActors()) { //Get a random actor int monsterIndex = Utility.random.Next(viableMonsters.Count()); ActorData a = new ActorData(xPos, yPos, viableMonsters[monsterIndex].monsterID); _monsterPointsUsed += viableMonsters[monsterIndex].pointCost; _monsters.Add(a); couldPlaceMonster = true; } tries++; } return(couldPlaceMonster); }
private void AddRandomRoomToPathIteration() { //Get a random room thats already in our path NewLevelGen_Room roomToBranchFrom = _roomsToBeUsed[Utility.random.Next(_roomsToBeUsed.Count)]; List <NewLevelGen_Room> neighbors = GetAdjacentRooms(roomToBranchFrom); NewLevelGen_Room roomToAdd = neighbors[Utility.random.Next(neighbors.Count)]; if (!_roomsToBeUsed.Contains(roomToAdd)) { _roomsToBeUsed.Add(roomToAdd); _adjacenciesToBeUsed.Add(GetAdjacencyBetweenRooms(roomToBranchFrom, roomToAdd)); AddExitLocationsToRoomsUsingAdjacency(_adjacenciesToBeUsed.Last()); } else if (!_adjacenciesToBeUsed.Contains(GetAdjacencyBetweenRooms(roomToBranchFrom, roomToAdd))) { _adjacenciesToBeUsed.Add(GetAdjacencyBetweenRooms(roomToBranchFrom, roomToAdd)); AddExitLocationsToRoomsUsingAdjacency(_adjacenciesToBeUsed.Last()); } }
private List <NewLevelGen_Room> GetAdjacentRooms(NewLevelGen_Room room) { List <NewLevelGen_Room> results = new List <NewLevelGen_Room>(); List <Tuple <NewLevelGen_Room, NewLevelGen_Room, int> > adjs = GetAdjacenciesForRoom(room); foreach (Tuple <NewLevelGen_Room, NewLevelGen_Room, int> adj in adjs) { if (adj.Item1.Equals(room)) { results.Add(adj.Item2); } else { results.Add(adj.Item1); } } return(results); }
public static bool TreasureRoomAGenerator(NewLevelGen_Room room, Tile[,] roomContents) { bool success = true; if (room.Size.X > 10 || room.Size.Y > 10) { return(false); } while (room.Exits.Count > 1) { roomContents[room.Exits[0].X - room.TopLeftCorner.X, room.Exits[0].Y - room.TopLeftCorner.Y].SetFeature(Tile_SimpleFeatureType.STONE_WALL); room.Exits.RemoveAt(0); } for (int i = 1; i < room.Size.X - 1; i++) { for (int k = 1; k < room.Size.Y - 1; k++) { roomContents[i, k].SetFeature(Tile_SimpleFeatureType.FLOOR); } } for (int i = 2; i < room.Size.X - 2; i++) { roomContents[i, 2].SetFeature(Tile_SimpleFeatureType.DEEP_WATER); roomContents[i, room.Size.Y - 3].SetFeature(Tile_SimpleFeatureType.DEEP_WATER); } for (int i = 2; i < room.Size.Y - 2; i++) { roomContents[2, i].SetFeature(Tile_SimpleFeatureType.DEEP_WATER); roomContents[room.Size.X - 3, i].SetFeature(Tile_SimpleFeatureType.DEEP_WATER); } roomContents[room.Size.X / 2, room.Size.Y / 2].SetFeature(Tile_SimpleFeatureType.PLAIN_CHEST); return(success); }
public bool PlaceItem() { bool couldPlaceItem = false; string spellForSpellbook = GenerateRandomSpellbookForDepth(_depth); int tries = 0; while (!couldPlaceItem && tries < 10) { //Select a random room int roomToTryIndex = Utility.random.Next(_rooms.Count); NewLevelGen_Room roomToTry = _rooms[roomToTryIndex]; //Get a random position in the room int xPos = roomToTry.TopLeftCorner.X; xPos += Utility.random.Next(1, roomToTry.Size.X / 2); xPos += Utility.random.Next(1, roomToTry.Size.X / 2); int yPos = roomToTry.TopLeftCorner.Y; yPos += Utility.random.Next(1, roomToTry.Size.Y / 2); yPos += Utility.random.Next(1, roomToTry.Size.Y / 2); if (!_map[xPos, yPos].ObstructsActors()) { //Place spellbook ItemData i = new ItemData(xPos, yPos, "itemSpellbook"); i.parameter = spellForSpellbook; _items.Add(i); couldPlaceItem = true; } tries++; } return(couldPlaceItem); }
private List <NewLevelGen_Room> GetLeastWeightPathBetweenRooms(NewLevelGen_Room source, NewLevelGen_Room target) { //Djikstra Dictionary <NewLevelGen_Room, int> distancesFromSource = new Dictionary <NewLevelGen_Room, int>(); //List of distance from the source to room X Dictionary <NewLevelGen_Room, NewLevelGen_Room> previousNodeFromSource = new Dictionary <NewLevelGen_Room, NewLevelGen_Room>(); //List of previous node in optimal path from source List <NewLevelGen_Room> unoptimizedRooms = new List <NewLevelGen_Room>(_rooms); foreach (NewLevelGen_Room room in _rooms) { distancesFromSource.Add(room, int.MaxValue); previousNodeFromSource.Add(room, null); } distancesFromSource[source] = 0; //Distance from source to itself is 0 while (unoptimizedRooms.Count > 0) { //Get unoptimizedRooms entry with shortest distance in distancesFromSource int shortest = int.MaxValue; NewLevelGen_Room nextRoom = unoptimizedRooms[0]; foreach (NewLevelGen_Room room in unoptimizedRooms) { if (distancesFromSource[room] < shortest) { shortest = distancesFromSource[room]; nextRoom = room; } } unoptimizedRooms.Remove(nextRoom); if (shortest == int.MaxValue) //If we haven't found a linked node { return(null); //No path exists! } foreach (Tuple <NewLevelGen_Room, NewLevelGen_Room, int> adj in GetAdjacenciesForRoom(nextRoom)) { NewLevelGen_Room neighbor = adj.Item1; if (neighbor.Equals(nextRoom)) { neighbor = adj.Item2; } int newDistance = distancesFromSource[nextRoom] + adj.Item3; if (newDistance < distancesFromSource[neighbor]) { distancesFromSource[neighbor] = newDistance; previousNodeFromSource[neighbor] = nextRoom; } } } List <NewLevelGen_Room> roomPath = new List <NewLevelGen_Room>(); NewLevelGen_Room nextRoomInFinalPath = target; while (previousNodeFromSource[nextRoomInFinalPath] != null) { roomPath.Add(nextRoomInFinalPath); nextRoomInFinalPath = previousNodeFromSource[nextRoomInFinalPath]; } roomPath.Add(source); roomPath.Reverse(); return(roomPath); }
public void MergeRoomsIteration() { //Pick a random room int candidateIndex = Utility.random.Next(_rooms.Count); NewLevelGen_Room candidateRoom = _rooms[candidateIndex]; //Get adjacent List <NewLevelGen_Room> adjRooms = GetAdjacentRooms(candidateRoom); if (adjRooms.Count == 0) { return; } //Pick a random adjacent room bool mergeCandidateFound = false; int mergeCandidateIndex = Utility.random.Next(adjRooms.Count); NewLevelGen_Room mergeCandidate = adjRooms[mergeCandidateIndex]; //A room needs to be A. the same dimensions and B. on the same X or Y axis to be considered for a merge if (candidateRoom.TopLeftCorner.X == mergeCandidate.TopLeftCorner.X || candidateRoom.TopLeftCorner.Y == mergeCandidate.TopLeftCorner.Y) { if (candidateRoom.Size.Equals(mergeCandidate.Size)) { mergeCandidateFound = true; } } if (mergeCandidateFound) { NewLevelGen_Room expandedRoom = candidateRoom; NewLevelGen_Room absorbedRoom = mergeCandidate; //Make sure we are keeping the room whose top left corner position will remain unchanged if (mergeCandidate.TopLeftCorner.X < candidateRoom.TopLeftCorner.X || mergeCandidate.TopLeftCorner.Y < candidateRoom.TopLeftCorner.Y) { expandedRoom = mergeCandidate; absorbedRoom = candidateRoom; } bool expandToTheRight = true; //Expand down if false if (expandedRoom.TopLeftCorner.X == absorbedRoom.TopLeftCorner.X) { expandToTheRight = false; } if (expandToTheRight) { expandedRoom.Size.X += absorbedRoom.Size.X - 1; } else { expandedRoom.Size.Y += absorbedRoom.Size.Y - 1; } //Get adjacent rooms to absorbedRoom, they are adjacent to us now List <NewLevelGen_Room> absorbedAdjacencies = GetAdjacentRooms(absorbedRoom); foreach (NewLevelGen_Room rm in absorbedAdjacencies) { if (rm != expandedRoom) { AddAdjacencyBetweenRooms(expandedRoom, rm); } } RemoveRoomAndAdjacencies(absorbedRoom); } }
private Tuple <NewLevelGen_Room, NewLevelGen_Room, int> GetAdjacencyBetweenRooms(NewLevelGen_Room roomA, NewLevelGen_Room roomB) { Tuple <NewLevelGen_Room, NewLevelGen_Room, int> result = null; foreach (Tuple <NewLevelGen_Room, NewLevelGen_Room, int> adj in _roomAdjacencies) { if (adj.Item1 == roomA && adj.Item2 == roomB || adj.Item1 == roomB && adj.Item2 == roomA) { result = adj; } } return(result); }
private void AddAdjacencyBetweenRooms(NewLevelGen_Room a, NewLevelGen_Room b) { int weight = _pathWeights[Utility.random.Next(_pathWeights.Length)]; _roomAdjacencies.Add(new Tuple <NewLevelGen_Room, NewLevelGen_Room, int>(a, b, weight)); }
private List <Tuple <NewLevelGen_Room, NewLevelGen_Room, int> > GetAdjacenciesForRoom(NewLevelGen_Room room) { List <Tuple <NewLevelGen_Room, NewLevelGen_Room, int> > items = new List <Tuple <NewLevelGen_Room, NewLevelGen_Room, int> >(); foreach (Tuple <NewLevelGen_Room, NewLevelGen_Room, int> adj in _roomAdjacencies) { if (adj.Item1.Equals(room) || adj.Item2.Equals(room)) { items.Add(adj); } } return(items); }