Пример #1
0
 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;
 }
Пример #2
0
    /// <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);
    }
Пример #3
0
    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);
    }