public override void GenerateTerrain(Rectangle dimensions)
        {
            Point mapSize = new Point(dimensions.Width + 1, dimensions.Height + 1);

            if (!sineSetup)
            {
                SetupSineWaves();
            }
            if (!caveSetup)
            {
                SetupCaves();
            }
            if (!tileSetup)
            {
                SetupTiles(new LayerSetings[0], new LayerSetings[0]);
            }
            if (!oreSetup)
            {
                SetupOres(new OreSetting[0]);
            }

            //GenerateBorders(dimensions);

            if (tilesMakeTerrain)
            {
                for (int x = 0; x < mapSize.X; x++)
                {
                    int[] tileLayerSineOffsets = new int[tileLayers.Length];
                    float waveValue            = 0;
                    for (int i = 0; i < tileLayerSineOffsets.Length; i++)
                    {
                        if (!tileLayers[i].useLastLayerWave)
                        {
                            waveValue = GetWaveValue(x + mapSize.X * i);
                        }
                        tileLayerSineOffsets[i] = (int)Math.Ceiling(waveValue + mapSize.Y * sineYOffset - tileLayers[i].GetOffset(mapSize.Y));
                    }

                    int[] wallLayerSineOffsets = new int[wallLayers.Length];
                    waveValue = 0;
                    for (int i = 0; i < wallLayerSineOffsets.Length; i++)
                    {
                        if (!wallLayers[i].useLastLayerWave)
                        {
                            waveValue = GetWaveValue(x - mapSize.X * (i + 1));
                        }
                        wallLayerSineOffsets[i] = (int)Math.Ceiling(waveValue + mapSize.Y * sineYOffset - wallLayers[i].GetOffset(mapSize.Y));
                    }
                    //PathOfModifiers.Log(
                    //    $"{GetWaveValue((float)x / dimensions.Width * (float)Math.PI * 2)}/" +
                    //    $"{waveValue}/" +
                    //    $"{surfaceHeight}/" +
                    //    $"{x}/" +
                    //    $"{x}");

                    for (int y = 0; y < mapSize.Y; y++)
                    {
                        int  wallToPlace = 0;
                        bool removeWall  = false;

                        int  tileToPlace = 0;
                        bool removeTile  = false;

                        Point tilePos = new Point(dimensions.X + x, dimensions.Y + y);

                        if (y <= mapSize.Y - tileLayerSineOffsets[0])
                        {
                            removeTile = true;
                        }
                        else
                        {
                            for (int i = 0; i < tileLayerSineOffsets.Length; i++)
                            {
                                if (y > mapSize.Y - tileLayerSineOffsets[i])
                                {
                                    tileToPlace = tileLayers[i].type;
                                }
                            }
                        }

                        if (y <= mapSize.Y - wallLayerSineOffsets[0])
                        {
                            removeWall = true;
                        }
                        else
                        {
                            for (int i = 0; i < wallLayerSineOffsets.Length; i++)
                            {
                                if (y > mapSize.Y - wallLayerSineOffsets[i])
                                {
                                    wallToPlace = wallLayers[i].type;
                                }
                            }
                        }

                        if (removeWall)
                        {
                            KillWall(tilePos);
                        }
                        else
                        {
                            PlaceWall(tilePos, wallToPlace);
                        }

                        if (removeTile)
                        {
                            KillTile(tilePos);
                        }
                        else
                        {
                            PlaceTile(tilePos, tileToPlace);
                        }
                    }
                }
            }
            if (tilesMakeCaves)
            {
                float noiseSeed = Main.rand.NextFloat(0, 255);
                for (int x = 0; x < mapSize.X; x++)
                {
                    for (int y = 0; y < mapSize.Y; y++)
                    {
                        Point tilePos = new Point(dimensions.X + x, dimensions.Y + y);
                        if (Noise.GetOctaveNoise(x / caveNoiseScale, y / caveNoiseScale, noiseSeed, caveNoiseOctaves) < caveNoiseThreshold)
                        {
                            KillTile(tilePos);
                        }
                    }
                }

                //((PathOfModifiers)mod).test = new List<Point>();
                Vector2[][] beziers = new Vector2[caveNBeziers][];
                for (int i = 0; i < beziers.Length; i++)
                {
                    beziers[i] = new Vector2[Main.rand.Next(caveBezierMinPoints, caveBezierMaxPoints + 1)];
                    Vector2[] bezier = beziers[i];
                    for (int j = 0; j < bezier.Length; j++)
                    {
                        bezier[j] = new Vector2(Main.rand.NextFloat(0, mapSize.X), Main.rand.NextFloat(0, mapSize.Y));
                    }

                    float   increment   = 1f / (Math.Max(mapSize.X, mapSize.Y) * 5);
                    Vector2 vTilePos    = Bezier.Bezier2D(bezier, 0);
                    Vector2 newVTilePos = Bezier.Bezier2D(bezier, increment);
                    KillTilesLine(vTilePos, newVTilePos, caveBezierWidth, dimensions);
                    for (float t = increment; t < 1; t += increment)
                    {
                        vTilePos = newVTilePos;
                        float newT = t + increment;
                        if (newT > 1)
                        {
                            newT = 1;
                        }
                        newVTilePos = Bezier.Bezier2D(bezier, newT);
                        KillTilesLine(vTilePos, newVTilePos, caveBezierWidth, dimensions);
                    }
                }
            }
            if (tilesMakeOres)
            {
                for (int i = 0; i < ores.Length; i++)
                {
                    int nPatches = Main.rand.Next((int)Math.Round(ores[i].frequency * (mapSize.X * mapSize.Y / 10000f)) + 1);
                    for (int j = 0; j < nPatches; j++)
                    {
                        Point tilePos = new Point(Main.rand.Next(mapSize.X), Main.rand.Next(mapSize.Y));
                        GeneratePatch(dimensions, tilePos, ores[i].patchSettings);
                    }
                }
            }
            if (tilesMakeTrees)
            {
                for (int x = 0; x < mapSize.X; x++)
                {
                    for (int y = 0; y < mapSize.Y; y++)
                    {
                        Point tilePos = new Point(dimensions.X + x, dimensions.Y + y);
                        WorldGen.GrowTree(tilePos.X, tilePos.Y);
                    }
                }
            }

            ResetSetup();
        }