Ejemplo n.º 1
0
 public AreaNode(Area area)
 {
     NodeID         = area.AreaID;
     Edges          = new HashSet <uint>();
     color          = -1;
     possibleBiomes = BiomeInfo.GetPossibleBiomesForTier(area.Tier);
 }
Ejemplo n.º 2
0
    public static BiomeInfo GetBiomeInfo(int x, int y)
    {
        float height = TerrainData.heightMap[x, y];

        // Find current biome
        int   biomeIndex       = 0;
        float biomeStartHeight = 0;

        for (int i = 0; i < biomes.Count; i++)
        {
            if (height <= biomes[i].height)
            {
                biomeIndex = i;
                break;
            }
            biomeStartHeight = biomes[i].height;
        }

        Biome biome   = biomes[biomeIndex];
        float sampleT = Mathf.InverseLerp(biomeStartHeight, biome.height, height);

        sampleT = (int)(sampleT * biome.numSteps) / (float)Mathf.Max(biome.numSteps, 1);

        // UV stores x: biomeIndex and y: val between 0 and 1 for how close to prev/next biome
        BiomeInfo biomeInfo = new BiomeInfo(biomeIndex, sampleT);

        return(biomeInfo);
    }
Ejemplo n.º 3
0
    public static bool IsShoreTile(int x, int y)
    {
        if (IsOutOfBounds(x, y))
        {
            return(false);
        }

        BiomeInfo biomeInfo = BiomeData.GetBiomeInfo(x, y);

        if (shoreTiles[x, y] != null)
        {
            return((bool)shoreTiles[x, y]);
        }

        if (IsWaterTile(x, y))
        {
            shoreTiles[x, y] = false;
            return(false);
        }

        if (IsWaterTile(x + 1, y) || IsWaterTile(x, y + 1) || IsWaterTile(x - 1, y) || IsWaterTile(x, y - 1))
        {
            shoreTiles[x, y] = true;
            return(true);
        }

        shoreTiles[x, y] = false;
        return(false);
    }
Ejemplo n.º 4
0
 /// <summary>
 /// Saves all biomes to the disk
 /// </summary>
 public static void SaveAllBiomeInfoToDisk()
 {
     foreach (BiomeType type in System.Enum.GetValues(typeof(BiomeType)))
     {
         SaveBiomeInfoToDisk(BiomeInfo.GetBiomeInfo(type));
     }
 }
    private void GenerateMap()
    {
        for (int currentX = 0; currentX < mapXSize * tileXScale; currentX += tileXScale)
        {
            for (int currentZ = 0; currentZ < mapZSize * tileZScale; currentZ += tileZScale)
            {
                BiomeInfo biomeToSpawnInfo = GetRandomBiomeInfo();

                GameObject tile = Instantiate(biomeToSpawnInfo.biome.gameObject, new Vector3(currentX, yHeight, currentZ), Quaternion.identity);
                tile.transform.localScale = new Vector3(tileXScale, 1, tileZScale);

                tile.transform.SetParent(this.transform);

                NetworkServer.Spawn(tile);

                GenerateBiome(biomeToSpawnInfo.biome, new Vector2(currentX, currentZ));
            }
        }

        NavMeshSurface surface = gameObject.AddComponent <NavMeshSurface>();

        surface.BuildNavMesh();

        //
        // Spawn enemies
        Assert.IsNotNull(m_enemyManager);
        foreach (int iClusterCount in aEnemyClusters)
        {
            List <BaseCharacter> enemies = new List <BaseCharacter>();
            if (m_enemyManager.SpawnCharacters(ECharacterType.enemy_zombie, iClusterCount, true, ref enemies))
            {
                //Debug.Log("Spawn success");
            }
        }
    }
Ejemplo n.º 6
0
    /// <summary>
    /// Save Biome Info to disk
    /// </summary>
    public static void SaveBiomeInfoToDisk(BiomeInfo info)
    {
        string data = SerializeBiomeInfo(info);

        //Debug.Log(data);

        using (FileStream file = new FileStream(GetSystemPath(GetBiomePathFromType(info.Type)), FileMode.Create))
            using (StreamWriter writer = new StreamWriter(file))
                writer.Write(data);
    }
Ejemplo n.º 7
0
    public Biome(BiomeInfo info, int tier)
    {
        Type = info.Type;
        Tier = tier;

        SpawnableEnemies  = new List <EnemyType>();
        SpawnableResource = new List <ResourceType>();
        SpawnableItems    = new List <ItemBaseType>();

        FillSpawnableEnemies(info.PossibleEnemiesToSpawn);
        FillSpawnableResources(info.PossibleResourceToSpawn);
        FillSpawnableItems(info.PossibleItemsToSpawn);
        //Debug.Log(this.ToString());
    }
Ejemplo n.º 8
0
    private void Awake()
    {
        if (_thisSingleton == null)
        {
            _thisSingleton         = this;
            ReadyToSpawnWorld      = false;
            PlayerSpawned          = false;
            _playerTransform       = GetComponent <Transform>();
            _mouseLook             = GetComponent <MouseLook>();
            _playerCamera          = GetComponent <Camera>();
            _updateBiomeTableTimer = new Timer(_updateBiomeTime);
            _biomeInfo             = _biomeInfoInstance;
            _spawnPosition         = _playerParent.position;

            UpdateBiomeInfo();
        }
        else
        {
            Destroy(this);
        }
    }
Ejemplo n.º 9
0
    public static bool IsWaterTile(int x, int y)
    {
        if (IsOutOfBounds(x, y))
        {
            return(false);
        }

        BiomeInfo biomeInfo = BiomeData.GetBiomeInfo(x, y);

        if (waterTiles[x, y] != null)
        {
            return((bool)waterTiles[x, y]);
        }

        if (biomeInfo.biomeIndex == 0)
        {
            waterTiles[x, y] = true;
            return(true);
        }

        waterTiles[x, y] = false;
        return(false);
    }
Ejemplo n.º 10
0
    void AddFace(Vector3[] sideVerts, int x, int y, MeshData meshData)
    {
        int vi = meshData.verts.Count;

        Color[] startCols = { water.startCol, sand.startCol, grass.startCol };
        Color[] endCols   = { water.endCol, sand.endCol, grass.endCol };

        meshData.verts.AddRange(sideVerts);

        BiomeInfo biomeInfo = BiomeData.GetBiomeInfo(x, y);

        Color color = Color.Lerp(startCols[biomeInfo.biomeIndex], endCols[biomeInfo.biomeIndex], biomeInfo.biomeDistance);

        meshData.colors.AddRange(new[] { color, color, color, color });

        meshData.tris.Add(vi);
        meshData.tris.Add(vi + 1);
        meshData.tris.Add(vi + 2);

        meshData.tris.Add(vi + 2);
        meshData.tris.Add(vi + 1);
        meshData.tris.Add(vi + 3);
    }
Ejemplo n.º 11
0
        public static char[,] generate(int width, int height, int typeDrd, int typeDst, int typeP, int typeM, int typeT, int typeF, int typeO, int resource)
        {
            // chance out of 1000
            int       resourceSparce  = resource;
            int       tundraAmount    = typeT;
            int       forestAmount    = typeF;
            int       mountainAmount  = typeM;
            int       plainAmount     = typeP;
            int       dreadlandAmount = typeDrd;
            int       desertAmount    = typeDst;
            int       oceanAmount     = typeO;
            int       rx          = width - 10;
            int       ry          = height - 10;
            const int MAX_CHANCE  = 1000;
            const int GOLD_CHANCE = 5;
            const int IRON_CHANCE = 2;
            const int MANA_CHANCE = 2;
            const int NumBio      = 800;
            const int Border      = 2000;
            const int numRivers   = 50;
            Random    r           = new Random();

            BiomeInfo[] bio = new BiomeInfo[NumBio + Border];
            for (int i = 0; i < bio.Length; i++)
            {
                bio[i] = new BiomeInfo();
            }

            //start terrain set
            int p = 0;

            while (p < 200)
            {
                //check for NO or LOW biome values.
                if (tundraAmount == 0)
                {
                }
                else
                {
                    bio[p].type = 'T';//Tundra
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (forestAmount == 0)
                {
                }
                else
                {
                    bio[p].type = 'F';//Forest
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (mountainAmount == 0)
                {
                }
                else
                {
                    bio[p].type = 'M';//Mountain
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (plainAmount == 0)
                {
                }
                else
                {
                    bio[p].type = '+';//Plain
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (dreadlandAmount == 0)
                {
                }
                else
                {
                    bio[p].type = '%';//Dreadland
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (desertAmount == 0)
                {
                }
                else
                {
                    bio[p].type = 'D';//Desert
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (oceanAmount == 0)
                {
                }
                else
                {
                    bio[p].type = '~'; //Ocean
                    bio[p].x    = r.Next(0, width);
                    bio[p].y    = r.Next(0, height);
                    p++;
                }

                //checks for DEFAULT/NORMAL biome value
                if (tundraAmount >= 2)
                {
                    bio[p].type = 'T';//Tundra
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (forestAmount >= 2)
                {
                    bio[p].type = 'F';//Forest
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (mountainAmount >= 2)
                {
                    bio[p].type = 'M';//Mountain
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (plainAmount >= 2)
                {
                    bio[p].type = '+';//Plain
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (dreadlandAmount >= 2)
                {
                    bio[p].type = '%';//Dreadland
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (desertAmount >= 2)
                {
                    bio[p].type = 'D';//Desert
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (oceanAmount >= 2)
                {
                    bio[p].type = '~'; //Ocean
                    bio[p].x    = r.Next(0, width);
                    bio[p].y    = r.Next(0, height);
                    p++;
                }
                //checks for HIGH biome value
                if (tundraAmount >= 3)
                {
                    bio[p].type = 'T';//Tundra
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (forestAmount >= 3)
                {
                    bio[p].type = 'F';//Forest
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (mountainAmount >= 3)
                {
                    bio[p].type = 'M';//Mountain
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (plainAmount >= 3)
                {
                    bio[p].type = '+';//Plain
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (dreadlandAmount >= 3)
                {
                    bio[p].type = '%';//Dreadland
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (desertAmount >= 3)
                {
                    bio[p].type = 'D';//Desert
                    bio[p].x    = r.Next(10, rx);
                    bio[p].y    = r.Next(10, ry);
                    p++;
                }
                if (oceanAmount >= 3)
                {
                    bio[p].type = '~'; //Ocean
                    bio[p].x    = r.Next(0, width);
                    bio[p].y    = r.Next(0, height);
                    p++;
                }
            }

            for (int i = p; i < 750; i++)
            {
                bio[i].x = r.Next(10, rx);
                bio[i].y = r.Next(10, ry);


                char nearest = '~';
                int  dist    = 5000;
                for (int z = 0; z < p; z++)
                {
                    int xdiff = bio[z].x - bio[i].x;
                    int ydiff = bio[z].y - bio[i].y;
                    int cdist = xdiff * xdiff + ydiff * ydiff;
                    if (cdist < dist)
                    {
                        nearest = bio[z].type;
                        dist    = cdist;
                    }
                }
                bio[i].type = nearest;
            }


            //Sets Border To Ocean Biome
            for (int k = 0; k < width; k++)
            {//goes through and sets top and bottom rows to Ocean biome.
                bio[NumBio + k * 2].type = '~';
                bio[NumBio + k * 2].x    = k;
                bio[NumBio + k * 2].y    = 0;

                bio[NumBio + k * 2 + 1].type = '~';
                bio[NumBio + k * 2 + 1].x    = k;
                bio[NumBio + k * 2 + 1].y    = height - 1;
            }
            for (int l = 0; l < height; l++)
            {//Sets Left and Right border to Ocean biome
                bio[NumBio + width + l * 2].type = '~';
                bio[NumBio + width + l * 2].x    = 0;
                bio[NumBio + width + l * 2].y    = l;

                bio[NumBio + width + l * 2 + 1].type = '~';
                bio[NumBio + width + l * 2 + 1].x    = width - 1;
                bio[NumBio + width + l * 2 + 1].y    = l;
            }

            char[,] field    = new char[width, height];
            int[,] elevation = new int[width, height];
            // i = y
            // j = x
            for (int j = 0; j < height; j++)
            {
                for (int i = 0; i < width; i++)
                {
                    char nearest = '~';
                    int  dist    = 5000;
                    for (int z = 0; z < NumBio + Border; z++)
                    {
                        int Xdiff = bio[z].x - i;
                        int Ydiff = bio[z].y - j;
                        int Cdist = Xdiff * Xdiff + Ydiff * Ydiff;
                        if (Cdist < dist)
                        {
                            nearest = bio[z].type;
                            dist    = Cdist;
                        }
                    }
                    field[i, j] = nearest;
                }
            }
            for (int i = 0; i < height; i++)
            {
                field[0, i]         = '~';  // left side
                field[width - 1, i] = '~';  // right side
            }
            for (int j = 0; j < width; j++)
            {
                field[j, 0]          = '~'; // top
                field[j, height - 1] = '~'; // bottom
            }

            //River Algorithm
            for (int j = 0; j < height; j++)
            {
                for (int i = 0; i < width; i++)
                {
                    if (field[i, j] == 'M')
                    {
                        elevation[i, j] = r.Next(40, 90);
                    }
                    if (field[i, j] == 'T')
                    {
                        elevation[i, j] = r.Next(10, 40);
                    }
                    if (field[i, j] == 'P')
                    {
                        elevation[i, j] = r.Next(5, 35);
                    }
                    if (field[i, j] == 'D')
                    {
                        elevation[i, j] = r.Next(10, 35);
                    }
                    if (field[i, j] == '%')
                    {
                        elevation[i, j] = r.Next(0, 20);
                    }
                    if (field[i, j] == '~')
                    {
                        elevation[i, j] = 0;
                    }
                    if (field[i, j] == 'F')
                    {
                        elevation[i, j] = r.Next(20, 60);
                    }
                }
            }

            for (int i = 0; i < numRivers; i++)
            {
                int riveRX = r.Next(50, width - 50);
                int riveRY = r.Next(50, height - 50);
                if (elevation[riveRX, riveRY] < 25)
                {
                    riveRX = r.Next(50, width - 50);
                    riveRY = r.Next(50, height - 50);
                }

                int lastDir     = 5;
                int Direction   = r.Next(0, 4); //0=North, 1=East, 2=South 3=West
                int riverLength = r.Next(0, 6);
                switch (riverLength)
                {//0=medium, 1=long, 2=extensive, else small
                case 0:
                    riverLength = r.Next(100, 180);
                    break;

                case 1:
                    riverLength = r.Next(200, 350);
                    break;

                case 2:
                    riverLength = r.Next(400, 600);
                    break;

                default:
                    riverLength = r.Next(30, 70);
                    break;
                }

                //make this random length
                field[riveRX, riveRY] = '-';//Designed for '-' character, but use ocean biome for now.
                for (int j = 0; j < riverLength; j++)
                {
                    int minHeight = 100;
                    if (lastDir != 2 && elevation[riveRX - 1, riveRY] < minHeight)
                    {
                        minHeight = elevation[riveRX - 1, riveRY];
                        Direction = 0;
                    }
                    if (lastDir != 3 && elevation[riveRX, riveRY + 1] < minHeight)
                    {
                        minHeight = elevation[riveRX, riveRY + 1];
                        Direction = 1;
                    }
                    if (lastDir != 0 && elevation[riveRX + 1, riveRY] < minHeight)
                    {
                        minHeight = elevation[riveRX + 1, riveRY];
                        Direction = 2;
                    }
                    if (lastDir != 1 && elevation[riveRX, riveRY - 1] < minHeight)
                    {
                        minHeight = elevation[riveRX, riveRY - 1];
                        Direction = 3;
                    }
                    switch (Direction)
                    {
                    case 0:
                        riveRX -= 1;
                        break;

                    case 1:
                        riveRY += 1;
                        break;

                    case 2:
                        riveRX += 1;
                        break;

                    case 3:
                        riveRY -= 1;
                        break;

                    default:
                        break;
                    }
                    lastDir = Direction;
                    if (field[riveRX, riveRY] == '~')
                    {
                        break;
                    }
                    else
                    {
                        field[riveRX, riveRY] = '-';
                    }
                }
            }
            //Adding Resources.
            for (int i = 0; i < height; i++)    // y
            {
                for (int j = 0; j < width; j++) // x
                {
                    if (field[j, i] == 'M')
                    {
                        if (r.Next(0, MAX_CHANCE) <= GOLD_CHANCE)
                        {
                            field[j, i] = 'G';//inserts gold mine resource
                        }
                    }
                    else if (field[j, i] == 'F')
                    {
                        if (r.Next(0, MAX_CHANCE) <= IRON_CHANCE)
                        {
                            field[j, i] = 'I';//sawmill for iron
                        }
                    }
                    else if (field[j, i] == '%')
                    {
                        if (r.Next(0, MAX_CHANCE) <= MANA_CHANCE)
                        {
                            field[j, i] = '*';//magic crystal resource
                        }
                    }
                    else if (r.Next(0, resourceSparce) <= 1)
                    {
                        if (field[j, i] != '~')
                        {
                            int resourceType = r.Next(0, 3);
                            if (resourceType == 0)
                            {
                                field[j, i] = 'L';
                            }
                            if (resourceType == 1)
                            {
                                field[j, i] = 'G';
                            }
                            if (resourceType == 2)
                            {
                                field[j, i] = '*';
                            }
                        }
                    }
                }
            }
            //Generates coastlines and gives rivers a direction.
            //each direction of river/Ocean will be set to a different character.
            for (int j = 1; j < width - 1; j++)
            {
                for (int i = 1; i < height - 1; i++)
                {
                    //******Ocean Border*****//
                    if (field[j, i] == '~')
                    {
                        bool[] land = new[] { false, false, false, false }; // Right, Bottom, Left, Top
                        land[0] = IsLand(field[j + 1, i]);
                        land[1] = IsLand(field[j, i + 1]);
                        land[2] = IsLand(field[j - 1, i]);
                        land[3] = IsLand(field[j, i - 1]);
                        int numberOfLandEdges = land.Sum(item => item ? 1 : 0);
                        if (numberOfLandEdges == 1)
                        {
                            if (land[0])
                            {
                                field[j, i] = '/';
                            }
                            else if (land[1])
                            {
                                field[j, i] = '&';
                            }
                            else if (land[2])
                            {
                                field[j, i] = '#';
                            }
                            else if (land[3])
                            {
                                field[j, i] = '@';
                            }
                        }
                        else if (numberOfLandEdges == 2) // Corners
                        {
                            if (land[0] && land[1])
                            {
                                field[j, i] = 'q';
                            }
                            else if (land[1] && land[2])
                            {
                                field[j, i] = 'w';
                            }
                            else if (land[2] && land[3])
                            {
                                field[j, i] = 'e';
                            }
                            else if (land[3] && land[0])
                            {
                                field[j, i] = 'r';
                            }
                        }
                        else if (numberOfLandEdges == 3) // Coves
                        {
                            if (land[0] && land[1] && land[2])
                            {
                                field[j, i] = 't';
                            }
                            else if (land[1] && land[2] && land[3])
                            {
                                field[j, i] = 'y';
                            }
                            else if (land[2] && land[3] && land[0])
                            {
                                field[j, i] = 'u';
                            }
                            else if (land[3] && land[0] && land[1])
                            {
                                field[j, i] = 'i';
                            }
                        }
                    }
                    //*****River Direction*****//
                    if (field[j, i] == '-')
                    {
                        if (IsRiver(field[j - 1, i]) && IsRiver(field[j + 1, i]))
                        {
                            field[j, i] = ',';                                                       // River running horizontal.
                        }
                        if (IsRiver(field[j, i - 1]) && IsRiver(field[j, i + 1]))
                        {
                            field[j, i] = '^';                                                       // River running vertical.
                        }
                        if (IsRiver(field[j + 1, i]) && IsRiver(field[j, i + 1]))
                        {
                            field[j, i] = '<';                                                       // River mouths at east and south.
                        }
                        if (IsRiver(field[j + 1, i]) && IsRiver(field[j, i - 1]))
                        {
                            field[j, i] = '[';                                                       // River mouths at east and north.
                        }
                        if (IsRiver(field[j - 1, i]) && IsRiver(field[j, i - 1]))
                        {
                            field[j, i] = ']';                                                       // River mouths at west and north.
                        }
                        if (IsRiver(field[j - 1, i]) && IsRiver(field[j, i + 1]))
                        {
                            field[j, i] = '>';                                                       // River mouths at west and south.
                        }
                        if (IsRiver(field[j, i - 1]) && IsRiver(field[j, i + 1]) && IsRiver(field[j - 1, i]) && IsRiver(field[j + 1, i]))
                        {
                            field[j, i] = 'X';                                                                                                               // 4-way river
                        }
                        if (IsRiver(field[j, i - 1]) && IsRiver(field[j, i + 1]) && IsRiver(field[j - 1, i]) && !IsRiver(field[j + 1, i]))
                        {
                            field[j, i] = 'p';                                                                                                                // triple river land at east
                        }
                        if (!IsRiver(field[j, i - 1]) && IsRiver(field[j, i + 1]) && IsRiver(field[j - 1, i]) && IsRiver(field[j + 1, i]))
                        {
                            field[j, i] = '|';                                                                                                                // triple river land at north
                        }
                        if (IsRiver(field[j, i - 1]) && !IsRiver(field[j, i + 1]) && IsRiver(field[j - 1, i]) && IsRiver(field[j + 1, i]))
                        {
                            field[j, i] = '_';                                                                                                                // triple river land at south
                        }
                        if (IsRiver(field[j, i - 1]) && IsRiver(field[j, i + 1]) && !IsRiver(field[j - 1, i]) && IsRiver(field[j + 1, i]))
                        {
                            field[j, i] = '?';                                                                                                                // triple river land at west
                        }
                    }
                }
            }
            return(field);
        }
Ejemplo n.º 12
0
 public RegularLevel(BiomeInfo biome) : base(biome)
 {
 }
Ejemplo n.º 13
0
 public static string SerializeBiomeInfo(BiomeInfo info)
 {
     return(JsonConvert.SerializeObject(info));
 }
Ejemplo n.º 14
0
 public BiomeInfo(BiomeInfo src) : this(src.Type, src.PossibleEnemiesToSpawn, src.PossibleItemsToSpawn, src.PossibleResourceToSpawn, src.MinMaxTier)
 {
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Generates a biome for this area
 /// </summary>
 /// <param name="type">the type of biome</param>
 public void GenerateBiomeForArea(BiomeType type)
 {
     AreaBiome = new Biome(BiomeInfo.GetBiomeInfo(type), Tier);
 }
Ejemplo n.º 16
0
        public static char[,] generate(int width, int height, int typeDrd, int typeDst, int typeP, int typeM, int typeT, int typeF, int typeO, int resource)
        {
            // chance out of 1000
            int resourceSparce = resource;
            int tundraAmount = typeT;
            int forestAmount = typeF;
            int mountainAmount = typeM;
            int plainAmount = typeP;
            int dreadlandAmount = typeDrd;
            int desertAmount = typeDst;
            int oceanAmount = typeO;
            int rx = width - 10;
            int ry = height - 10;
            const int MAX_CHANCE = 1000;
            const int GOLD_CHANCE = 5;
            const int IRON_CHANCE = 2;
            const int MANA_CHANCE = 2;
            const int NumBio = 800;
            const int Border = 2000;
            const int numRivers = 50;
            Random r = new Random();
            BiomeInfo[] bio = new BiomeInfo[NumBio + Border];
            for (int i = 0; i < bio.Length; i++)
            {
                bio[i] = new BiomeInfo();
            }

            //start terrain set
            int p = 0;
            while (p < 200)
            {
                //check for NO or LOW biome values.
                if (tundraAmount == 0) { }
                else
                {
                    bio[p].type = 'T';//Tundra
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (forestAmount == 0) { }
                else
                {
                    bio[p].type = 'F';//Forest
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (mountainAmount == 0) { }
                else
                {
                    bio[p].type = 'M';//Mountain
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (plainAmount == 0) { }
                else
                {
                    bio[p].type = '+';//Plain
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (dreadlandAmount == 0) { }
                else
                {
                    bio[p].type = '%';//Dreadland
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (desertAmount == 0) { }
                else
                {
                    bio[p].type = 'D';//Desert
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (oceanAmount == 0) { }
                else
                {
                    bio[p].type = '~'; //Ocean
                    bio[p].x = r.Next(0, width);
                    bio[p].y = r.Next(0, height);
                    p++;
                }

                //checks for DEFAULT/NORMAL biome value
                if (tundraAmount >= 2)
                {
                    bio[p].type = 'T';//Tundra
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (forestAmount >= 2)
                {
                    bio[p].type = 'F';//Forest
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (mountainAmount >= 2)
                {
                    bio[p].type = 'M';//Mountain
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (plainAmount >= 2)
                {
                    bio[p].type = '+';//Plain
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (dreadlandAmount >= 2)
                {
                    bio[p].type = '%';//Dreadland
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (desertAmount >= 2)
                {
                    bio[p].type = 'D';//Desert
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (oceanAmount >= 2)
                {
                    bio[p].type = '~'; //Ocean
                    bio[p].x = r.Next(0, width);
                    bio[p].y = r.Next(0, height);
                    p++;
                }
                //checks for HIGH biome value
                if (tundraAmount >= 3)
                {
                    bio[p].type = 'T';//Tundra
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (forestAmount >= 3)
                {
                    bio[p].type = 'F';//Forest
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (mountainAmount >= 3)
                {
                    bio[p].type = 'M';//Mountain
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (plainAmount >= 3)
                {
                    bio[p].type = '+';//Plain
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (dreadlandAmount >= 3)
                {
                    bio[p].type = '%';//Dreadland
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (desertAmount >= 3)
                {
                    bio[p].type = 'D';//Desert
                    bio[p].x = r.Next(10, rx);
                    bio[p].y = r.Next(10, ry);
                    p++;
                }
                if (oceanAmount >= 3)
                {
                    bio[p].type = '~'; //Ocean
                    bio[p].x = r.Next(0, width);
                    bio[p].y = r.Next(0, height);
                    p++;
                }
            }

            for (int i = p; i < 750; i++)
            {
                bio[i].x = r.Next(10, rx);
                bio[i].y = r.Next(10, ry);

                char nearest = '~';
                int dist = 5000;
                for (int z = 0; z < p; z++)
                {
                    int xdiff = bio[z].x - bio[i].x;
                    int ydiff = bio[z].y - bio[i].y;
                    int cdist = xdiff * xdiff + ydiff * ydiff;
                    if (cdist < dist)
                    {
                        nearest = bio[z].type;
                        dist = cdist;
                    }

                }
                bio[i].type = nearest;
            }

            //Sets Border To Ocean Biome
            for (int k = 0; k < width; k++)
            {//goes through and sets top and bottom rows to Ocean biome.
                bio[NumBio + k * 2].type = '~';
                bio[NumBio + k * 2].x = k;
                bio[NumBio + k * 2].y = 0;

                bio[NumBio + k * 2 + 1].type = '~';
                bio[NumBio + k * 2 + 1].x = k;
                bio[NumBio + k * 2 + 1].y = height - 1;
            }
            for (int l = 0; l < height; l++)
            {//Sets Left and Right border to Ocean biome
                bio[NumBio + width + l * 2].type = '~';
                bio[NumBio + width + l * 2].x = 0;
                bio[NumBio + width + l * 2].y = l;

                bio[NumBio + width + l * 2 + 1].type = '~';
                bio[NumBio + width + l * 2 + 1].x = width - 1;
                bio[NumBio + width + l * 2 + 1].y = l;
            }

            char[,] field = new char[width, height];
            int[,] elevation = new int[width, height];
            // i = y
            // j = x
            for (int j = 0; j < height; j++)
            {
                for (int i = 0; i < width; i++)
                {
                    char nearest = '~';
                    int dist = 5000;
                    for (int z = 0; z < NumBio + Border; z++)
                    {
                        int Xdiff = bio[z].x - i;
                        int Ydiff = bio[z].y - j;
                        int Cdist = Xdiff * Xdiff + Ydiff * Ydiff;
                        if (Cdist < dist)
                        {
                            nearest = bio[z].type;
                            dist = Cdist;
                        }

                    }
                    field[i, j] = nearest;
                }
            }
            for (int i = 0; i < height; i++)
            {
                field[0, i] = '~';          // left side
                field[width - 1, i] = '~';  // right side
            }
            for (int j = 0; j < width; j++)
            {
                field[j, 0] = '~';          // top
                field[j, height - 1] = '~';  // bottom
            }

            //River Algorithm
            for (int j = 0; j < height; j++)
            {
                for (int i = 0; i < width; i++)
                {
                    if (field[i, j] == 'M')
                        elevation[i, j] = r.Next(40, 90);
                    if (field[i, j] == 'T')
                        elevation[i, j] = r.Next(10, 40);
                    if (field[i, j] == 'P')
                        elevation[i, j] = r.Next(5, 35);
                    if (field[i, j] == 'D')
                        elevation[i, j] = r.Next(10, 35);
                    if (field[i, j] == '%')
                        elevation[i, j] = r.Next(0, 20);
                    if (field[i, j] == '~')
                        elevation[i, j] = 0;
                    if (field[i, j] == 'F')
                        elevation[i, j] = r.Next(20, 60);
                }
            }

            for (int i = 0; i < numRivers; i++)
            {
                int riveRX = r.Next(50, width - 50);
                int riveRY = r.Next(50, height - 50);
                if (elevation[riveRX, riveRY] < 25)
                {
                    riveRX = r.Next(50, width - 50);
                    riveRY = r.Next(50, height - 50);
                }

                int lastDir = 5;
                int Direction = r.Next(0, 4); //0=North, 1=East, 2=South 3=West
                int riverLength = r.Next(0, 6);
                switch (riverLength)
                {//0=medium, 1=long, 2=extensive, else small
                    case 0:
                        riverLength = r.Next(100, 180);
                        break;
                    case 1:
                        riverLength = r.Next(200, 350);
                        break;
                    case 2:
                        riverLength = r.Next(400, 600);
                        break;
                    default:
                        riverLength = r.Next(30, 70);
                        break;
                }

                //make this random length
                field[riveRX, riveRY] = '-';//Designed for '-' character, but use ocean biome for now.
                for (int j = 0; j < riverLength; j++)
                {
                    int minHeight = 100;
                    if (lastDir != 2 && elevation[riveRX - 1, riveRY] < minHeight)
                    {
                        minHeight = elevation[riveRX - 1, riveRY];
                        Direction = 0;
                    }
                    if (lastDir != 3 && elevation[riveRX, riveRY + 1] < minHeight)
                    {
                        minHeight = elevation[riveRX, riveRY + 1];
                        Direction = 1;
                    }
                    if (lastDir != 0 && elevation[riveRX + 1, riveRY] < minHeight)
                    {
                        minHeight = elevation[riveRX + 1, riveRY];
                        Direction = 2;
                    }
                    if (lastDir != 1 && elevation[riveRX, riveRY - 1] < minHeight)
                    {
                        minHeight = elevation[riveRX, riveRY - 1];
                        Direction = 3;
                    }
                    switch (Direction)
                    {
                        case 0:
                            riveRX -= 1;
                            break;
                        case 1:
                            riveRY += 1;
                            break;
                        case 2:
                            riveRX += 1;
                            break;
                        case 3:
                            riveRY -= 1;
                            break;
                        default:
                            break;
                    }
                    lastDir = Direction;
                    if (field[riveRX, riveRY] == '~')
                        break;
                    else
                        field[riveRX, riveRY] = '-';
                }
            }
            //Adding Resources.
            for (int i = 0; i < height; i++) // y
            {
                for (int j = 0; j < width; j++) // x
                {
                    if (field[j, i] == 'M')
                    {
                        if (r.Next(0, MAX_CHANCE) <= GOLD_CHANCE)
                            field[j, i] = 'G';//inserts gold mine resource
                    }
                    else if (field[j, i] == 'F')
                    {
                        if (r.Next(0, MAX_CHANCE) <= IRON_CHANCE)
                            field[j, i] = 'I';//sawmill for iron
                    }
                    else if (field[j, i] == '%')
                    {
                        if (r.Next(0, MAX_CHANCE) <= MANA_CHANCE)
                            field[j, i] = '*';//magic crystal resource
                    }
                    else if (r.Next(0, resourceSparce) <= 1)
                    {
                        if (field[j, i] != '~')
                        {
                            int resourceType = r.Next(0, 3);
                            if (resourceType == 0)
                                field[j, i] = 'L';
                            if (resourceType == 1)
                                field[j, i] = 'G';
                            if (resourceType == 2)
                                field[j, i] = '*';
                        }
                    }

                }
            }
            //Generates coastlines and gives rivers a direction.
            //each direction of river/Ocean will be set to a different character.
            for (int j = 1; j < width - 1; j++)
            {
                for (int i = 1; i < height - 1; i++)
                {
                    //******Ocean Border*****//
                    if (field[j, i] == '~')
                    {
                        bool[] land = new[] {false, false, false, false}; // Right, Bottom, Left, Top
                        land[0] = IsLand(field[j + 1, i]);
                        land[1] = IsLand(field[j, i + 1]);
                        land[2] = IsLand(field[j - 1, i]);
                        land[3] = IsLand(field[j, i - 1]);
                        int numberOfLandEdges = land.Sum(item => item ? 1 : 0);
                        if (numberOfLandEdges == 1)
                        {
                            if (land[0]) field[j, i] = '/';
                            else if (land[1]) field[j, i] = '&';
                            else if (land[2]) field[j, i] = '#';
                            else if (land[3]) field[j, i] = '@';
                        }
                        else if (numberOfLandEdges == 2) // Corners
                        {
                            if (land[0] && land[1]) field[j, i] = 'q';
                            else if (land[1] && land[2]) field[j, i] = 'w';
                            else if (land[2] && land[3]) field[j, i] = 'e';
                            else if (land[3] && land[0]) field[j, i] = 'r';
                        }
                        else if (numberOfLandEdges == 3) // Coves
                        {
                            if (land[0] && land[1] && land[2]) field[j, i] = 't';
                            else if (land[1] && land[2] && land[3]) field[j, i] = 'y';
                            else if (land[2] && land[3] && land[0]) field[j, i] = 'u';
                            else if (land[3] && land[0] && land[1]) field[j, i] = 'i';
                        }
                    }
                    //*****River Direction*****//
                    if (field[j, i] == '-')
                    {
                        if (IsRiver(field[j - 1, i]) && IsRiver(field[j + 1, i])) field[j, i] = ','; // River running horizontal.
                        if (IsRiver(field[j, i - 1]) && IsRiver(field[j, i + 1])) field[j, i] = '^'; // River running vertical.
                        if (IsRiver(field[j + 1, i]) && IsRiver(field[j, i + 1])) field[j, i] = '<'; // River mouths at east and south.
                        if (IsRiver(field[j + 1, i]) && IsRiver(field[j, i - 1])) field[j, i] = '['; // River mouths at east and north.
                        if (IsRiver(field[j - 1, i]) && IsRiver(field[j, i - 1])) field[j, i] = ']'; // River mouths at west and north.
                        if (IsRiver(field[j - 1, i]) && IsRiver(field[j, i + 1])) field[j, i] = '>'; // River mouths at west and south.
                        if (IsRiver(field[j, i - 1]) && IsRiver(field[j, i + 1]) && IsRiver(field[j - 1, i]) && IsRiver(field[j + 1, i])) field[j, i] = 'X'; // 4-way river
                        if (IsRiver(field[j, i - 1]) && IsRiver(field[j, i + 1]) && IsRiver(field[j - 1, i]) && !IsRiver(field[j + 1, i])) field[j, i] = 'p'; // triple river land at east
                        if (!IsRiver(field[j, i - 1]) && IsRiver(field[j, i + 1]) && IsRiver(field[j - 1, i]) && IsRiver(field[j + 1, i])) field[j, i] = '|'; // triple river land at north
                        if (IsRiver(field[j, i - 1]) && !IsRiver(field[j, i + 1]) && IsRiver(field[j - 1, i]) && IsRiver(field[j + 1, i])) field[j, i] = '_'; // triple river land at south
                        if (IsRiver(field[j, i - 1]) && IsRiver(field[j, i + 1]) && !IsRiver(field[j - 1, i]) && IsRiver(field[j + 1, i])) field[j, i] = '?'; // triple river land at west
                    }
                }
            }
            return field;
        }