Beispiel #1
0
        public override void ModifyWorldGenTasks(List <GenPass> tasks, ref float totalWeight)
        {
            int resetIndex   = tasks.FindIndex(i => i.Name == "Reset");
            int terrainIndex = tasks.FindIndex(i => i.Name == "Terrain");

            if (terrainIndex != -1)
            {
                tasks.Insert(resetIndex + 1, new PassLegacy("Deciding World Evil", (progress) => DecideEvil(progress)));
            }

            int evilIndex = tasks.FindIndex(i => i.Name == "Corruption");

            if (evilIndex != -1)
            {
                vanillaEvilPass  = tasks[evilIndex];
                tasks[evilIndex] = new PassLegacy("Corruption", (progress) => GenerateEvil(progress, tasks[resetIndex] as PassLegacy));
            }
        }
        public UIPassItem(int order, GenPass pass, string text, float textScale = 1, bool large = false)
        {
            this.pass  = pass;
            this.order = order;
            //TextColor = Color.Blue;

            Width         = StyleDimension.Fill;
            Height.Pixels = 15;

            uitext = new UIText(text, textScale, large);
            uitext.Left.Set(20, 0);
            Append(uitext);

            UIImageButton close = new UIImageButton(WorldGenPreviewer.instance.GetTexture("closeButton"));

            close.OnClick += RemoveThisPass;
            //close.Left.Set(-45, 1);
            close.Left.Set(0, 0);
            Append(close);
        }
        public UIWorldLoadSpecial(GenerationProgress progress)
        {
            instance        = this;
            menuTexture     = ModContent.GetTexture("WorldGenPreviewer/menu");
            previousTexture = ModContent.GetTexture("WorldGenPreviewer/previous");
            playTexture     = ModContent.GetTexture("WorldGenPreviewer/play");
            pauseTexture    = ModContent.GetTexture("WorldGenPreviewer/pause");
            nextTexture     = ModContent.GetTexture("WorldGenPreviewer/next");

            menuButton     = new UIImageButton(menuTexture);
            previousButton = new UIImageButton(previousTexture);
            playButton     = new UIImageButton(playTexture);
            pauseButton    = new UIImageButton(pauseTexture);
            nextButton     = new UIImageButton(nextTexture);
            cancelButton   = new UIImageButton(ModContent.GetTexture("WorldGenPreviewer/cancel"));

            passesPanel = new UIPanel();
            passesPanel.SetPadding(3);
            passesPanel.Left.Pixels = listHidden ? panelWidth : 0;
            passesPanel.HAlign      = 1f;
            passesPanel.Top.Set(0f, 0f);
            passesPanel.Width.Set(panelWidth, 0f);
            passesPanel.Height.Set(0f, 1f);
            passesPanel.BackgroundColor = new Color(73, 94, 171);

            passesList = new UIList();
            passesList.Width.Set(0f, 1f);
            passesList.Height.Set(0f, 1f);
            passesList.ListPadding = 12f;
            passesPanel.Append(passesList);

            UIScrollbar passesListScrollbar = new UIScrollbar();

            passesListScrollbar.SetView(100f, 1000f);
            passesListScrollbar.Height.Set(0f, 1f);
            passesListScrollbar.HAlign = 1f;
            passesPanel.Append(passesListScrollbar);
            passesList.SetScrollbar(passesListScrollbar);

            int order = 0;

            for (int i = 0; i < WorldGenPreviewerModWorld.generationPasses.Count; i++)
            {
                GenPass pass = WorldGenPreviewerModWorld.generationPasses[i];
                if (pass.Name != "World Gen Paused")
                {
                    order++;
                    UIPassItem testLabel = new UIPassItem(order, pass, pass.Name, 1f, false);
                    //testLabel.Top.Pixels = y;
                    //y += 10;
                    passesList.Add(testLabel);
                    //passesPanel.Append(testLabel);
                }
            }
            Append(passesPanel);

            buttonPanel = new UIPanel();
            buttonPanel.SetPadding(0);
            //buttonPanel.Left.Set(0f, .5f);
            buttonPanel.HAlign = 0.5f;
            buttonPanel.Top.Set(180f, 0f);
            //buttonPanel.Width.Set(170f, 0f);
            buttonPanel.Height.Set(32 + spacing * 2 + 16, 0f);
            buttonPanel.BackgroundColor = new Color(73, 94, 171);

            float calculatedWidth = spacing;

            buttonPanel.Append(menuButton);
            menuButton.OnClick    += MenuClick;
            menuButton.Left.Pixels = calculatedWidth;
            menuButton.Top.Pixels  = spacing;
            calculatedWidth       += spacing + 32;

            buttonPanel.Append(previousButton);
            previousButton.OnClick    += PreviousClick;
            previousButton.Left.Pixels = calculatedWidth;
            previousButton.Top.Pixels  = spacing;
            calculatedWidth           += spacing + 32;

            buttonPanel.Append(playButton);
            playButton.OnClick    += PlayClick;
            playButton.Left.Pixels = calculatedWidth;
            playButton.Top.Pixels  = spacing;
            calculatedWidth       += spacing + 32;

            buttonPanel.Append(pauseButton);
            pauseButton.OnClick    += PauseClick;
            pauseButton.Left.Pixels = calculatedWidth;
            pauseButton.Top.Pixels  = spacing;
            calculatedWidth        += spacing + 32;

            buttonPanel.Append(nextButton);
            nextButton.OnClick    += NextClick;
            nextButton.Left.Pixels = calculatedWidth;
            nextButton.Top.Pixels  = spacing;
            calculatedWidth       += spacing + 32;

            buttonPanel.Append(cancelButton);
            cancelButton.OnClick    += CancelClick;
            cancelButton.Left.Pixels = calculatedWidth;
            cancelButton.Top.Pixels  = spacing;
            calculatedWidth         += spacing + 32;

            statusLabel        = new UIText("Status: Normal", 1f, false);
            statusLabel.VAlign = 1f;
            statusLabel.HAlign = 0.5f;
            statusLabel.Top.Set(-5f, 0f);
            buttonPanel.Append(statusLabel);

            buttonPanel.Width.Pixels = calculatedWidth;
            Append(buttonPanel);

            this._progressBar.Top.Pixels = 70f;
            this._progressBar.HAlign     = 0.5f;
            this._progressBar.VAlign     = 0f;
            this._progressBar.Recalculate();
            this._progressMessage.CopyStyle(this._progressBar);
            UIHeader expr_78_cp_0 = this._progressMessage;

            expr_78_cp_0.Top.Pixels = expr_78_cp_0.Top.Pixels - 70f;
            this._progressMessage.Recalculate();
            this._progress = progress;
            base.Append(this._progressBar);
            base.Append(this._progressMessage);
        }
        public override void ModifyWorldGenTasks(List <GenPass> tasks, ref float totalWeight)
        {
            generationPasses = tasks;
            // Reset Terrain
            // Reset Special Terrain
            // or after reset
            Main.skipMenu = false;             // Reset skipMenu to false so that worlds can be saved
            int ResetStepIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Reset"));

            if (ResetStepIndex != -1)
            {
                tasks.Insert(ResetStepIndex + 1, new PassLegacy("Special World Gen Progress", delegate(GenerationProgress progress, GameConfiguration config)
                {
                    Main.FixUIScale();
                    progress.Message = "Setting up Special World Gen Progress";
                    Main.refreshMap  = true;
                    var a            = new UIWorldLoadSpecial(progress);

                    Main.MenuUI.SetState(a);

                    Main.updateMap          = false;
                    Main.mapStyle           = 0;
                    Main.mapFullscreen      = true;
                    Main.mapFullscreenScale = Main.screenWidth / (float)Main.maxTilesX * 0.8f;
                    Main.mapMinX            = 0;
                    Main.mapMinY            = 0;
                    Main.mapMaxX            = Main.maxTilesX;
                    Main.mapMaxY            = Main.maxTilesY;
                    Main.mapFullscreenPos   = new Vector2(Main.maxTilesX / 2, Main.maxTilesY / 2);
                    Main.mapReady           = true;
                }));

                // Reset Special Paused Terrain Paused ...
                for (int i = tasks.Count - 1; i >= ResetStepIndex + 2; i--)
                {
                    string  name     = tasks[i - 1].Name;
                    GenPass previous = tasks[i - 1];
                    GenPass next     = tasks[i];
                    tasks.Insert(i, new PassLegacy("World Gen Paused", delegate(GenerationProgress progress, GameConfiguration config)
                    {
                        UIWorldLoadSpecial.BadPass = next.Name == "Expand World";

                        foreach (var item in UIWorldLoadSpecial.instance.passesList._items)
                        {
                            UIPassItem passitem = item as UIPassItem;
                            if (passitem.pass == previous)
                            {
                                passitem.Complete();
                                break;
                            }
                        }
                        if (!continueWorldGen)
                        {
                            progress.Message = "World Gen Paused after " + name;
                            UIWorldLoadSpecial.instance.statusLabel.SetText("Status: Paused");
                        }
                        while (true)
                        {
                            if (repeatPreviousStep)
                            {
                                repeatPreviousStep = false;
                                //string previousStatus = UIWorldLoadSpecial.instance.statusLabel.SetText
                                UIWorldLoadSpecial.instance.statusLabel.SetText("Status: Doing Previous Step Again");
                                previous.Apply(progress, config);
                                //if (continueWorldGen)
                                //{
                                //	UIWorldLoadSpecial.instance.statusLabel.SetText("Status: Normal");
                                //}
                                //else
                                //{
                                UIWorldLoadSpecial.instance.statusLabel.SetText("Status: Paused");
                                //}
                            }
                            if (continueWorldGen)
                            {
                                if (pauseAfterContinue)
                                {
                                    pauseAfterContinue = false;
                                    continueWorldGen   = false;
                                }
                                break;
                            }
                        }
                    }));
                }
            }
            else
            {
                Mod.Logger.Error("WorldGenPreviewer mod unable to do it's thing since someone removed reset step");
            }
        }
        public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight) {
            List<Vector2> majorCaves = new List<Vector2> { };
            // Because world generation is like layering several images ontop of each other, we need to do some steps between the original world generation steps.
            GenPass smooth = tasks.Find(t => t.Name == "Smooth World");
            tasks.RemoveRange(1, tasks.Count - 1);

            tasks.Add(new PassLegacy("aberrant", delegate (GenerationProgress progress) {
                progress.Message = "Starting an Aberrant World";
                Main.worldSurface = Main.maxTilesY * 0.2; //vanilla does this at 0.3, but we like caves
                Main.rockLayer = Main.worldSurface + 100;
                for (int x = 0; x < Main.maxTilesX; x++) {
                    for (int y = (int)Main.rockLayer; y < Main.maxTilesY - 200; y++) {
                        Main.tile[x, y].active(active: true);
                        Main.tile[x, y].type = TileID.Stone;
                        Main.tile[x, y].frameX = -1;
                        Main.tile[x, y].frameY = -1;
                    }
                    progress.Set(x / (float)Main.maxTilesX);
                }

            }));
            bool[,] map = new bool[Main.maxTilesX / 3, Main.maxTilesY / 3];
            tasks.Add(new PassLegacy("tunnels", delegate (GenerationProgress progress) {

                progress.Message = "Planning out small caves";
                for (int x = 0; x < map.GetLength(0); x++) {
                    for (int y = (int)Main.rockLayer / 3; y < map.GetLength(1); y++) {
                        map[x, y] = WorldGen.genRand.NextFloat(0, 1) <= 0.37 ? true : false;
                    }
                }
                progress.Set(0.33f);
                map = minorCave(map);
                progress.Set(0.66f);
                map = minorCave(map);
                progress.Set(1f);
            }));
            tasks.Add(new PassLegacy("tunnelling", delegate (GenerationProgress progress) {
                progress.Message = "Digging out small caves";

                for (int x = 0; x < map.GetLength(0); x++) {
                    for (int y = 0; y < map.GetLength(1); y++) {
                        if (map[x, y] == true) {
                            WorldGen.TileRunner(x*3, y*3, 6, WorldGen.genRand.Next(5,10), -1);
                        }
                    }
                    progress.Set(x / (float)map.GetLength(0));
                }

            }));
            tasks.Add(new PassLegacy("surface", delegate (GenerationProgress progress) {
                progress.Message = "Creating Surface Layers";
                int halfPoint = (int)Main.worldSurface + 50; //Prefer if this was not a constant that has to be changed if the worldgen changes too much
                for (int x = 0; x < Main.maxTilesX; x++) {
                    WorldGen.TileRunner(x, (int)Main.rockLayer, 10, 10, TileID.Stone, true);
                        Main.tile[x, y].frameX = -1;
                        Main.tile[x, y].frameY = -1;
                    }


                    WorldGen.TileRunner(x, (int)Main.worldSurface, 20, 20, TileID.Sand, true);
                    WorldGen.TileRunner(x, (int)halfPoint, 20, 20, TileID.HardenedSand, true);
                    WorldGen.TileRunner(x, (int)Main.rockLayer, 20, 20, TileID.Stone, true);// This is cursed. Call excorcist
                }
            }));

            tasks.Add(new PassLegacy("major", delegate (GenerationProgress progress) {
                progress.Message = "Hiring excavation crews...";
                //between 700 and 1200 on a normal world


                int padding = 500;
                int steps = (int)((Main.maxTilesX - padding * 2) * 0.002); //comes out to about 22 steps on a large world
                int stepSize = (int)(Main.maxTilesX / (float)steps);
                Vector2 last = default;
                for (int i = 0; i < steps; i++) {
                    Vector2 node = new Vector2(500 + i * stepSize, WorldGen.genRand.Next((int)Main.rockLayer, Main.maxTilesY - 200));
                    if (!Equals(last, default(Vector2))) {
                        majorCaves.AddRange(bresenham(last, node));
                    }
                    last = node;
                }
            }));
            tasks.Add(new PassLegacy("drawMajor", delegate (GenerationProgress progress) {
                progress.Message = "Making Big Caves";
                for (int i = 0; i < majorCaves.Count; i++) {
                    if (WorldGen.genRand.Next(3) != 0)
                        WorldGen.TileRunner((int)majorCaves[i].X, (int)majorCaves[i].Y, 50, WorldGen.genRand.Next(40, 80), TileID.Stone, true);
                    progress.Set(i / (float)(majorCaves.Count * 2));
                }
                for (int i = 0; i < majorCaves.Count; i++) {
                    WorldGen.TileRunner((int)majorCaves[i].X, (int)majorCaves[i].Y, 25, WorldGen.genRand.Next(10, 50), -1, true);
                    progress.Set(0.5f + i / ((float)majorCaves.Count * 2));
                }
            }));

            tasks.Add(new PassLegacy("Shinies", delegate (GenerationProgress progress) {
                progress.Message = "Dropping Precious Stones";
                for (int x = 0; x < Main.maxTilesX; x++) {
                    for (int y = (int)Main.rockLayer; y < Main.maxTilesY - 200; y++) {

                        int distanceFromTop = y - (int)Main.rockLayer;
                        if (WorldGen.genRand.Next(0, (distanceFromTop + 100) * 100) == 0) WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 10), WorldGen.genRand.Next(5, 10), TileType<IonizingMetal>());
                        else if (WorldGen.genRand.Next(0, 2000) == 0) WorldGen.TileRunner(x, y, WorldGen.genRand.Next(5, 10), WorldGen.genRand.Next(5, 10), TileID.Iron);
                    }
                }
            }));
            tasks.Add(new PassLegacy("placeDirt", delegate (GenerationProgress progress) {
                progress.Message = "Gardening..."; List<Vector2> inner20 = new List<Vector2> { };
                List<Vector2> gardenSites = new List<Vector2> { };
                if (majorCaves.Count <= 21) inner20 = majorCaves;
                else {
                    int center = majorCaves.Count / 2;
                    inner20 = majorCaves.GetRange(center - 10, 20);
                }
                for (int i = 0; i < 20; i++) {
                    if (inner20.Count != 0) {
                        int index = WorldGen.genRand.Next(inner20.Count);
                        Vector2 dropDirt = inner20[index];
                        inner20.RemoveAt(index);

                        while (!Main.tile[(int)dropDirt.X, (int)dropDirt.Y].active()) {
                            dropDirt.Y++;
                        }
                        WorldGen.TileRunner((int)dropDirt.X, (int)dropDirt.Y, WorldGen.genRand.Next(1, 6), WorldGen.genRand.Next(10, 30), TileID.Dirt);
                        gardenSites.Add(dropDirt);
                    } else i = 20;
                }
                List<Vector2> inner25 = new List<Vector2> { };
                inner25 = majorCaves.GetRange(majorCaves.Count / 2 - majorCaves.Count / 8, majorCaves.Count / 4);
                for (int i = 0; i < 50; i++) {
                    if (inner25.Count != 0) {
                        int index = WorldGen.genRand.Next(inner25.Count);
                        Vector2 dropDirt = inner25[index];
                        inner25.RemoveAt(index);

                        while (!Main.tile[(int)dropDirt.X, (int)dropDirt.Y].active()) {
                            dropDirt.Y++;
                        }
                        WorldGen.TileRunner((int)dropDirt.X, (int)dropDirt.Y, 20, WorldGen.genRand.Next(10, 50), 0);
                        gardenSites.Add(dropDirt);
                    } else i = 50;
                }
                for (int i = 0; i < gardenSites.Count; i++) {
                    garden((int)gardenSites[i].X, (int)gardenSites[i].Y, 20);
                }
            }));
            tasks.Add(new PassLegacy("Smoothing", delegate (GenerationProgress progress) {
                progress.Message = "Erosion";
                smooth.Apply(new GenerationProgress()); // I have no clue how Smoothing does it's GenerationProgress so I decided to hold my ears and sing LALALALA
            }));

            tasks.Add(new PassLegacy("Rail", delegate (GenerationProgress progress) {

                progress.Message = "Abandoning Mineshafts";


                //Constants
                int areaStart = (int)Main.worldSurface;//At which height could the shaft enter?
                int areaEnd = Main.maxTilesY - 200;//At which height could the shaft not enter?
                int buffer = 100;//Distance from the edge of the world.
                int minSize = 100; // To keep a good size for tunnels.
                int maximumShafts = WorldGen.genRand.Next(0, 8);
                //int maximumShafts = WorldGen.genRand.Next(50,55);
                for (int thisShaft = 0; thisShaft < maximumShafts; thisShaft += 1) {
                    //One time constants
                    int startPos = buffer + (int)WorldGen.genRand.Next(0, Main.maxTilesX - minSize - buffer - 50);
                    int endPos = WorldGen.genRand.Next(startPos + 50, Main.maxTilesX - buffer);
                    int height = WorldGen.genRand.Next(areaStart, areaEnd);
                    int railtype = 0;
                    for (int i = startPos; i < endPos; i += 5) {
                        progress.Set(((float)thisShaft + (((float)i - (float)startPos) / (float)((float)endPos - (float)startPos))) / (float)maximumShafts);

                        //Place supports
                        if ((int)(i - startPos) / 5 % 10 == 5 && !Main.tile[i, height + 1].active()) {
                            for (int y = height + 1; !Main.tile[i, y].active() || !Main.tile[i, y + 1].active(); y++) {
                                setRect(i, y, 1, 1, TileID.WoodenBeam, true);
                            }
                        }

                        //
                        if (WorldGen.genRand.Next(0, 3) == 0) {
                            railtype = getNextRailType(railtype);
                        }

                        //Determine if railtype is invalid

                        switch (railtype) {
                            case 3:
                                //Only do case 3 if we have to
                                bool blocksExist = false;
                                for (int j = i; j < i + 5; j++) {
                                    if (blocksExist == false && Main.tile[j, height].active()) {
                                        blocksExist = true;
                                    }
                                }
                                if (!blocksExist) {
                                    railtype = getNextRailType(railtype);
                                }
                                break;
                            case 4:
                                if (height + 4 > areaEnd) {
                                    railtype = 5;
                                }   //For 4 and 5 make sure it makes sense
                                break;
                            case 5:
                                if (height - 4 < areaStart) {
                                    railtype = 4;
                                }
                                break;
                        }


                        //Switch to each type of rail
                        switch (railtype) {
                            case 1:
                                break;//Sometimes just... don't build any rail, or roof.
                            case 2:
                                setRect(i, height - 1, 5, 1, TileID.MinecartTrack, true);//Track
                                break;//Only Rail
                            case 3://No walls
                                setRect(i, height, 5, 1, TileID.WoodBlock, true); //Floor
                                setRect(i, height - 1, 5, 1, TileID.MinecartTrack, true);//Track
                                setRect(i, height - 6, 5, 1, TileID.WoodBlock, false); //Roof

                                //Walls
                                if (i % 2 == 1) { //Because of dumb patterns I have to do this
                                    setRectWall(i, height - 4, 1, 4, WallID.Wood);
                                    setRectWall(i + 1, height - 4, 1, 4, WallID.BorealWood);
                                    setRectWall(i + 2, height - 4, 1, 4, WallID.Wood);
                                    setRectWall(i + 3, height - 4, 1, 4, WallID.BorealWood);
                                    setRectWall(i + 4, height - 4, 1, 4, WallID.Wood);
                                } else {
                                    setRectWall(i, height - 4, 1, 4, WallID.BorealWood);
                                    setRectWall(i + 1, height - 4, 1, 4, WallID.Wood);
                                    setRectWall(i + 2, height - 4, 1, 4, WallID.BorealWood);
                                    setRectWall(i + 3, height - 4, 1, 4, WallID.Wood);
                                    setRectWall(i + 4, height - 4, 1, 4, WallID.BorealWood);
                                }

                                break;//Case 3 is wierd, it tries to let some debris through, not a bug.. its a feature!
                            case 4://Down

                                for (int j = i; j < i + 5; j++) {
                                    if (j % 2 == 0) {
                                        setRectWall(j, height - 5, 1, 6, WallID.Wood);
                                    } else {
                                        setRectWall(j, height - 5, 1, 6, WallID.BorealWood);
                                    }
                                    setRect(j, height - 6, 1, 7, -1, forced: true);                 //Air
                                    setRect(j, height - 6, 1, 1, TileID.WoodBlock, forced: true); //Roof
                                    setRect(j, height, 1, 1, TileID.WoodBlock, forced: true); //Floor
                                    setRect(j, height - 1, 1, 1, TileID.MinecartTrack, forced: true);//Track
                                    height = height + 1;


                                }

                                break;
                            case 5://UP

                                for (int j = i; j < i + 5; j++) {
                                    if (j % 2 == 0) {
                                        setRectWall(j, height - 6, 1, 6, WallID.Wood);
                                    } else {
                                        setRectWall(j, height - 6, 1, 6, WallID.BorealWood);
                                    }

                                    setRect(j, height - 6, 5, 6, -1, true);                 //Air
                                    setRect(j, height, 1, 1, TileID.WoodBlock, true);//Floor
                                    setRect(j, height - 1, 1, 1, TileID.MinecartTrack, true);//Track
                                    setRect(j, height - 7, 1, 1, TileID.WoodBlock, true); //Roof
                                    height = height - 1;

                                }

                                break;
                            default:
                                //Make boring straight tunnels
                                setRect(i, height - 5, 5, 4, -1, true);                 //Air
                                setRect(i, height, 5, 1, TileID.WoodBlock, true); //Floor
                                setRect(i, height - 1, 5, 1, TileID.MinecartTrack, true);//Track
                                setRect(i, height - 6, 5, 1, TileID.WoodBlock, true); //Roof

                                //Walls
                                if (i % 2 == 1) { //Because of dumb patterns I have to do this
                                    setRectWall(i, height - 5, 1, 5, WallID.Wood);
                                    setRectWall(i + 1, height - 5, 1, 5, WallID.BorealWood);
                                    setRectWall(i + 2, height - 5, 1, 5, WallID.Wood);
                                    setRectWall(i + 3, height - 5, 1, 5, WallID.BorealWood);
                                    setRectWall(i + 4, height - 5, 1, 5, WallID.Wood);
                                } else {
                                    setRectWall(i, height - 5, 1, 5, WallID.BorealWood);
                                    setRectWall(i + 1, height - 5, 1, 5, WallID.Wood);
                                    setRectWall(i + 2, height - 5, 1, 5, WallID.BorealWood);
                                    setRectWall(i + 3, height - 5, 1, 5, WallID.Wood);
                                    setRectWall(i + 4, height - 5, 1, 5, WallID.BorealWood);
                                }

                                if ((int)(i - startPos) / 5 % 10 == 0) {
                                    try { // This is dumb. Please do better, Seriously.
                                        setRect(i, height - 2, 1, 1, mod.TileType("IonizedLantern"));
                                    } catch (Exception e) {
                                        mod.Logger.Debug("Failed Ionized Lantern at (" + i + "," + (height - 2) + ") default rail track");
                                    }
                                }
                                break;
                        }
                    }
                }
            }));
            tasks.Add(new PassLegacy("Final", delegate (GenerationProgress progress) {

                Vector2 spawnpoint = majorCaves[majorCaves.Count / 2];
                while (!Main.tile[(int)spawnpoint.X, (int)spawnpoint.Y].active() || Main.tile[(int)spawnpoint.X, (int)spawnpoint.Y].type == TileID.Trees) {
                    spawnpoint.Y++;
                }
                setRect((int)spawnpoint.X - 7, (int)spawnpoint.Y - 5, 14, 4, forced: true);
                setRectWall((int)spawnpoint.X - 6, (int)spawnpoint.Y - 4, 13, 4, WallID.Wood);
                // ceiling
                setRect((int)spawnpoint.X - 7, (int)spawnpoint.Y - 5, 15, 1, TileID.WoodBlock, true);
                //floor
                setRect((int)spawnpoint.X - 7, (int)spawnpoint.Y, 14, 1, TileID.WoodBlock, true);
                //left wall
                setRect((int)spawnpoint.X - 7, (int)spawnpoint.Y - 4, 1, 4, TileID.WoodenBeam, forced: true);
                //right wall
                setRect((int)spawnpoint.X + 7, (int)spawnpoint.Y - 4, 1, 4, TileID.WoodenBeam, forced: true);
                //torches
                WorldGen.KillTile((int)spawnpoint.X - 4, (int)spawnpoint.Y - 3);
                WorldGen.KillTile((int)spawnpoint.X - 4, (int)spawnpoint.Y - 2);
                WorldGen.PlaceTile((int)spawnpoint.X - 4, (int)spawnpoint.Y - 3, TileType<Tiles.IonizedLantern>());
                WorldGen.KillTile((int)spawnpoint.X + 4, (int)spawnpoint.Y - 3);
                WorldGen.KillTile((int)spawnpoint.X + 4, (int)spawnpoint.Y - 2);
                WorldGen.PlaceTile((int)spawnpoint.X + 4, (int)spawnpoint.Y - 3, TileType<Tiles.IonizedLantern>());

                //finally set spawnpoint
                Main.spawnTileX = (int)spawnpoint.X;
                Main.spawnTileY = (int)spawnpoint.Y - 1;

                //merchant
                NPC.NewNPC(Main.spawnTileX * 16, Main.spawnTileY * 16, NPCID.Merchant, 1);
            }));
        }