public GenerationAreaSettings(GenerationAreaSettings settings = null) { if (settings == null) { return; } area_name = settings.area_name; weight = settings.weight; type = settings.type; width = settings.width; height = settings.height; generationTurfSettings = settings.generationTurfSettings; }
/// <summary> /// This is super scuffed just saying /// </summary> /// <param name="turfs"></param> /// <param name="door_x"></param> /// <param name="door_y"></param> /// <param name="door_dir"></param> /// <returns></returns> public List <GenerationAreaSettings> CheckSpace(Turf[,] turfs, int door_x, int door_y, Direction door_dir) { //Fetch the doors List <GenerationTurfSettings> doors = new List <GenerationTurfSettings>(); foreach (GenerationTurfSettings turfSetting in generationTurfSettings) { if (turfSetting.door_dir_x != 0 || turfSetting.door_dir_y != 0) { doors.Add(turfSetting); } } List <GenerationAreaSettings> potentialOutputs = new List <GenerationAreaSettings>(); //Generate translated copies of myself where the doors attack to the entrance points foreach (GenerationTurfSettings door in doors) { GenerationAreaSettings transformedRoom = new GenerationAreaSettings(this); while (door.door_dir_x == -1 && door_dir != Direction.WEST || door.door_dir_x == 1 && door_dir != Direction.EAST || door.door_dir_y == -1 && door_dir != Direction.NORTH || door.door_dir_y == 1 && door_dir != Direction.SOUTH) { //Rotate until it points AWAY from the door int widthTemp = transformedRoom.width; transformedRoom.width = -transformedRoom.height; transformedRoom.height = widthTemp; foreach (GenerationTurfSettings element in transformedRoom.generationTurfSettings) { //DEBUG If room rotations are f****d, problem is here int temp = element.x; element.x = -element.y; element.y = temp; temp = element.door_dir_x; element.door_dir_x = -element.door_dir_y; element.door_dir_y = temp; } } //Translate room so the door lines up :') Vector2 targetPosition = new Vector2(door_x + (door_dir == Direction.EAST ? -1 : door_dir == Direction.WEST ? 1 : 0), door_y + (door_dir == Direction.NORTH ? 1 : door_dir == Direction.SOUTH ? -1 : 0)); Vector2 currentPosition = new Vector2(door.x, door.y); //DEBUG If room is misaligned problem is here Vector2 deltaPosition = targetPosition - currentPosition; foreach (GenerationTurfSettings element in transformedRoom.generationTurfSettings) { element.x += (int)deltaPosition.x; element.y += (int)deltaPosition.y; } potentialOutputs.Add(transformedRoom); } //Alright, now for the <i>Easy</i> part, just check if the tile is occupied, if ANY tile in it is, don't bother returning it. //Otherwise, retrun all that work and let the level generator do its job List <GenerationAreaSettings> validOutputs = new List <GenerationAreaSettings>(); foreach (GenerationAreaSettings potentialRoom in potentialOutputs) { bool roomValid = true; foreach (GenerationTurfSettings tiles in potentialRoom.generationTurfSettings) { //Check if room is out of bounds if (turfs.GetLength(0) <= tiles.x || turfs.GetLength(0) <= tiles.y || tiles.x < 0 || tiles.y < 0) { roomValid = false; break; } //Check if room overlaps another try { if (turfs[tiles.x, tiles.y] == null || turfs[tiles.x, tiles.y].calculated) { roomValid = false; break; } } catch { Log.ServerMessage(turfs.GetLength(0) + "," + tiles.x + "," + tiles.y); roomValid = false; break; } //Check if doors attack to a room they are not meant to (attatch to occupied with no door = bad) if (tiles.door_dir_x != 0 || tiles.door_dir_y != 0) { Vector2Int doorPos = new Vector2Int(tiles.x + tiles.door_dir_x, tiles.y + tiles.door_dir_y); //Check if it goes out of bounds if (doorPos.x >= turfs.GetLength(0) || doorPos.y >= turfs.GetLength(0) || doorPos.x < 0 || doorPos.y < 0) { roomValid = false; break; } //Check if a door is there (if occupied) if (turfs[doorPos.x, doorPos.y].calculated && turfs[doorPos.x, doorPos.y].occupied) { roomValid = false; break; } } //Final check, see if any rooms that border us have doors that need filling foreach (Vector2Int direction in directions) { Vector2Int checkPos = new Vector2Int(tiles.x + direction.x, tiles.y + direction.y); //Check if it goes out of bounds if (checkPos.x >= turfs.GetLength(0) || checkPos.y >= turfs.GetLength(0) || checkPos.x < 0 || checkPos.y < 0) { roomValid = false; break; } //Check if occupied and has door if (turfs[checkPos.x, checkPos.y].door && (tiles.door_dir_x == 0 && tiles.door_dir_y == 0)) { roomValid = false; break; } } } if (roomValid) { //Convert tiledata to generation area settings data validOutputs.Add(potentialRoom); } } return(validOutputs); }
public static List <GenerationAreaSettings> ParseGenerationDataJson(Resource textResource) { TextAsset textAsset = (TextAsset)textResource.loadedResources["level_gen_areas"]; List <GenerationAreaSettings> generationAreaSettings = new List <GenerationAreaSettings>(); GenerationAreaSettings currentArea = new GenerationAreaSettings(); GenerationTurfSettings currentTurf = new GenerationTurfSettings(); bool readingTiles = false; foreach (string line in textAsset.text.Split('\n')) { if (!readingTiles) { if (line.Contains(":")) { string[] parts = Sanatise(line).Split(':'); switch (parts[0]) { case "name": currentArea.area_name = parts[1]; continue; case "probability": int probability = 0; int.TryParse(parts[1], out probability); currentArea.weight = probability; continue; case "type": currentArea.type = parts[1]; continue; case "width": int width = 0; int.TryParse(parts[1], out width); currentArea.width = width; continue; case "height": int height = 0; int.TryParse(parts[1], out height); currentArea.height = height; continue; case "tiles": readingTiles = true; continue; } } if (line.Contains("}")) { //end of currentArea generationAreaSettings.Add(currentArea); currentArea = new GenerationAreaSettings(); continue; } } else { string[] parts = Sanatise(line).Split(':'); switch (parts[0]) { case "x": int x = 0; int.TryParse(parts[1], out x); currentTurf.x = x; continue; case "y": int y = 0; int.TryParse(parts[1], out y); currentTurf.y = y; continue; case "door_dir_x": int door_dir_x = 0; int.TryParse(parts[1], out door_dir_x); currentTurf.door_dir_x = door_dir_x; continue; case "door_dir_y": int door_dir_y = 0; int.TryParse(parts[1], out door_dir_y); currentTurf.door_dir_y = door_dir_y; continue; case "type": currentTurf.type = parts[1]; continue; } if (line.Contains("}")) { currentArea.generationTurfSettings.Add(currentTurf); currentTurf = new GenerationTurfSettings(); continue; } if (line.Contains("]")) { readingTiles = false; continue; } } } return(generationAreaSettings); }
public Turf[,] GenerateActiveLayer(int size = 255) { MeshFilter objectMesh = ((GameObject)levelResources.loadedResources["turf"]).GetComponentInChildren <MeshFilter>(); List <GenerationAreaSettings> areaData = ReadGenerationSettings(); Turf[,] turfs = new Turf[size, size]; //Count how many rooms were made int roomCount = 0; int successfulCount = 0; //Populate array with default values for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { turfs[x, y] = new Turf(x, y); } } List <TileData> tilesToProcess = new List <TileData>(); TileData initialRoom = new TileData(); initialRoom.connection_x = 1; initialRoom.connection_y = 0; initialRoom.x = size / 2; initialRoom.y = size / 2; tilesToProcess.Add(initialRoom); //Generate the rooms while (tilesToProcess.Count > 0) { //Log the amount of rooms roomCount++; //Log.Print("Processing tile at " + tilesToProcess[0].x + "," + tilesToProcess[0].y + " with direction " + tilesToProcess[0].connection_x + "," + tilesToProcess[0].connection_y); //Generate a list of rooms that can be used List <GenerationAreaSettings> validRooms = new List <GenerationAreaSettings>(); //Check which areas can be placed foreach (GenerationAreaSettings setting in areaData) { Direction direction = Direction.NORTH; if (tilesToProcess[0].connection_x == 1) { direction = Direction.WEST; } else if (tilesToProcess[0].connection_x == -1) { direction = Direction.EAST; } else if (tilesToProcess[0].connection_y == 1) { direction = Direction.NORTH; } else if (tilesToProcess[0].connection_y == -1) { direction = Direction.SOUTH; } else { Log.PrintError("Major error, door direction invalid"); } validRooms.AddRange(setting.CheckSpace(turfs, tilesToProcess[0].x, tilesToProcess[0].y, direction)); } //Check weights //Place it if (validRooms.Count == 0) { tilesToProcess.RemoveAt(0); continue; } GenerationAreaSettings chosenArea = Helpers.Pick(validRooms); foreach (GenerationTurfSettings tile in chosenArea.generationTurfSettings) { //Debug.Log("[" + tile.x + "]" + "[" + tile.y + "] : Added turf, type : [" + tile.type + "]" + (tile.type == "wall").ToString()); //DEBUG, REMOVE WHEN DONE turfs[tile.x, tile.y].calculated = true; turfs[tile.x, tile.y].occupied = tile.type == "wall"; turfs[tile.x, tile.y].hasCeiling = tile.type != "sky"; turfs[tile.x, tile.y].hasFloor = tile.type != "pit"; turfs[tile.x, tile.y].turfMesh = objectMesh.sharedMesh; if (tile.door_dir_x != 0 || tile.door_dir_y != 0) { turfs[tile.x, tile.y].door = true; } if (tile.door_dir_x != 0 || tile.door_dir_y != 0) { TileData data = new TileData(); data.x = tile.x; data.y = tile.y; data.connection_x = tile.door_dir_x; data.connection_y = tile.door_dir_y; tilesToProcess.Add(data); //Log.Print("Added new tile to be processed at " + data.x + "," + data.y + "," + data.connection_x + "," + data.connection_y); } } successfulCount++; tilesToProcess.RemoveAt(0); } Log.Print("<color=green>Successfully generated " + roomCount + " rooms, of which " + successfulCount + " were successful</color>"); return(turfs); }