/// <summary>
        /// Convenience binding to place a given tile object from its corner. Places from the bottom. Uses vanilla's
        /// object placement method. Applies `WorldGen.SquareTileFrame(...)`.
        /// </summary>
        /// <param name="leftX"></param>
        /// <param name="bottomY"></param>
        /// <param name="type"></param>
        /// <param name="style"></param>
        /// <param name="direction"></param>
        /// <param name="forced">Attempts to ignore anchor checks and place the tile regardless.</param>
        /// <returns></returns>
        public static bool PlaceObject(int leftX, int bottomY, ushort type, int style = 0, sbyte direction = -1, bool forced = false)
        {
            var tileObjData = TileObjectData.GetTileData(type, style);

            if (tileObjData == null)
            {
                return(false);
            }

            int x = leftX + tileObjData.Origin.X;
            int y = bottomY + (tileObjData.Height - 1) - tileObjData.Origin.Y;            // + tileObjData.Height - 1;

/*int BLAH = 0;
 * Timers.SetTimer( "BLHA_"+ type, 5, false, () => {
 *      Dust.QuickDust( new Point(leftX,bottomY), Color.Red);
 *      Dust.QuickDust( new Point(x,y), Color.Green);
 *      return BLAH++ < 50;
 * } );*/
            TileObject tileObj;

            if (TileObject.CanPlace(x, y, type, style, direction, out tileObj) || forced)
            {
                bool isPlaced = TileObject.Place(tileObj);
                if (isPlaced)
                {
                    WorldGen.SquareTileFrame(x, y);
                }
                return(isPlaced);
            }
            return(false);
            //Main.player[255].direction = direction;
            //return WorldGen.PlaceTile( x, y, type, false, false, 255, style );
        }
예제 #2
0
        public static bool PlaceIceChest(int x, int y, ushort type = 21, bool notNearOtherChests = false, int style = 0)
        {
            int        num = -1;
            TileObject toBePlaced;

            if (TileObject.CanPlace(x, y, type, style, 1, out toBePlaced, false))
            {
                bool flag = true;
                if (notNearOtherChests && Chest.NearOtherChests(x - 1, y - 1))
                {
                    flag = false;
                }
                if (flag)
                {
                    TileObject.Place(toBePlaced);
                    num = Chest.CreateChest(toBePlaced.xCoord, toBePlaced.yCoord, -1);
                }
            }
            else
            {
                num = -1;
            }
            // if (num != -1 && Main.netMode == 1)
            // {
            //     NetMessage.SendData(34, -1, -1, "", 0, (float)x, (float)y, (float)style, 0, 0, 0);
            // }
            return(true);
        }
예제 #3
0
        public bool TryPlacingDragonBall(int whichDragonBall, int offsetX, int offsetY)
        {
            // dragon ball already exists, bail out.
            if (IsExistingDragonBall(whichDragonBall))
            {
                return(true);
            }
            TileObject tileObjectOut;
            int        dragonBallType = GetDbType(whichDragonBall);

            if (!TileObject.CanPlace(offsetX, offsetY, dragonBallType, 0, -1, out tileObjectOut, true,
                                     false))
            {
                return(false);
            }

            CacheDragonBallLocation(whichDragonBall, new Point(offsetX, offsetY));

            WorldGen.PlaceObject(offsetX, offsetY, dragonBallType, true);
            NetMessage.SendTileSquare(-1, offsetX, offsetY, 1, TileChangeType.None);
            if (Main.netMode == NetmodeID.Server)
            {
                NetworkHelper.playerSync.SendAllDragonBallLocations();
            }

            return(true);
        }
예제 #4
0
        public static bool TryPlacingDragonball(int whichDragonball, int offsetX, int offsetY, Player ignorePlayer = null)
        {
            // dragon ball already exists, bail out.
            if (IsExistingDragonBall(whichDragonball))
            {
                return(true);
            }

            // dragon ball is in a connected player's inventory. This isn't fool proof.
            if (IsDragonBallWithPlayers(whichDragonball, ignorePlayer))
            {
                return(true);
            }

            // dragon ball is in a chest somewhere. This also isn't fool proof.
            if (IsDragonBallInventoried(whichDragonball))
            {
                return(true);
            }

            TileObject toBePlaced;

            if (TileObject.CanPlace(offsetX, offsetY, DBZMOD.instance.TileType(GetDragonBallTileTypeFromNumber(whichDragonball)), 0, -1, out toBePlaced, true, false))
            {
                WorldGen.PlaceObject(offsetX, offsetY, DBZMOD.instance.TileType(GetDragonBallTileTypeFromNumber(whichDragonball)), true);
                int dbIndex = whichDragonball - 1;
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #5
0
        internal void Place(int x, int y, int type, int style, int dir)
        {
            Main.tile[x, y].active(false);
            TileObject tileObject;

            if (TileObject.CanPlace(x, y, type, style, dir, out tileObject))
            {
                TileObject.Place(tileObject);
            }
        }
예제 #6
0
        public override void PostUpdate()
        {
            if (Main.netMode != NetmodeID.Server && player.whoAmI == Main.myPlayer)
            {
                if (GotChest && Main.mouseRight && Main.mouseRightRelease && dist / 16f <= 4) //Issues with mp
                {
                    Vector2 NewChestPos = new Vector2((int)mousePos.X / 16, (int)mousePos.Y / 16);

                    if (CheckChestPlacing((int)NewChestPos.X, (int)NewChestPos.Y))
                    {
                        PlaceChest((int)NewChestPos.X, (int)NewChestPos.Y);
                        //WorldGen.SquareTileFrame((int)NewChestPos.X, (int)NewChestPos.Y, true);

                        GotChest = false;

                        //Create dropoff sound
                        Main.PlaySound(SoundID.DoorClosed, (int)player.Center.X, (int)player.Center.Y);
                    }
                    else
                    {
                        Main.PlaySound(SoundID.Duck, (int)player.Center.X, (int)player.Center.Y);
                    }
                }

                if (GotChest && dist / 16f <= 4)
                {
                    TileObject tileObject = default(TileObject);
                    TileObject.CanPlace(Player.tileTargetX, Player.tileTargetY, 21, (ChestType / 36), 1, out tileObject, true);

                    if (!firstTick)
                    {
                        player.inventory[inventorySpot].SetDefaults(ModContent.ItemType <Box>());
                        firstTick = true;
                    }
                }

                if (GotChest)
                {
                    player.AddBuff(ModContent.BuffType <MovingDebuff>(), 10);
                }


                //Remove the item once the player gets done
                if (!GotChest)
                {
                    foreach (Item slot in player.inventory)
                    {
                        if (slot.type == ModContent.ItemType <Box>())
                        {
                            slot.SetDefaults(0);
                        }
                    }
                }
            }
        }
예제 #7
0
 public static bool PlaceObject(int x, int y, int type, bool mute = false, int style = 0, int random = -1, int direction = -1)
 {
     if (!TileObject.CanPlace(x, y, type, style, direction, out TileObject toBePlaced, false))
     {
         return(false);
     }
     toBePlaced.random = random;
     if (TileObject.Place(toBePlaced) && !mute)
     {
         WorldGen.SquareTileFrame(x, y, true);
     }
     return(false);
 }
예제 #8
0
 public static bool PlaceObject(int x, int y, int type, bool mute = false, int style = 0, int alternate = 0, int random = -1, int direction = -1)
 {
     TileObject toBePlaced;
     if(!TileObject.CanPlace(x, y, type, style, direction, out toBePlaced, false)) {
         return false;
     }
     toBePlaced.random = random;
     if(TileObject.Place(toBePlaced) && !mute) {
         WorldGen.SquareTileFrame(x, y, true);
         //   Main.PlaySound(0, x * 16, y * 16, 1, 1f, 0f);
     }
     return false;
 }
예제 #9
0
        public static bool PlaceChest(int x, int y, ushort type = 21, bool notNearOtherChests = false, int style = 0)
        {
            bool       b = false;
            TileObject toBePlaced;

            if (TileObject.CanPlace(x, y, type, style, 1, out toBePlaced, false))
            {
                bool flag = !(notNearOtherChests && Chest.NearOtherChests(x - 1, y - 1));

                if (flag)
                {
                    b = TileObject.Place(toBePlaced);
                    if (b)
                    {
                        Chest.CreateChest(toBePlaced.xCoord, toBePlaced.yCoord, -1);
                    }
                }
            }
            return(b);

            /*
             * var chest_num = WorldGen.PlaceChest(x, y);
             *
             * if (chest_num != -1)
             * {
             *  Item[] chest = Main.chest[chest_num].item;
             *
             *  int itemsToPlace = Main.rand.Next(1, 4);
             *  for (int i = 0; i < itemsToPlace; i++)
             *  {
             *      if (Main.rand.Next(0, 5) == 0)
             *      {
             *          //God Escence
             *          chest[i].SetDefaults(ModContent.ItemType<cameraObscura>());
             *      }
             *      else if (Main.rand.Next(0, 2) == 0)
             *      {
             *          //Broken hero's sword
             *          chest[i].SetDefaults(ItemID.BrokenHeroSword);
             *      }
             *      else
             *      {
             *          //Broken hero's sword
             *          chest[i].SetDefaults(ItemID.SwordStatue);
             *      }
             *  }
             *  Main.chest[chest_num].item = chest;
             * }
             */
        }
예제 #10
0
        public static bool BetterPlaceObject(int x, int y, int type, bool mute = false, int style = 0, int random = -1, int direction = -1)
        {
            if (!TileObject.CanPlace(x, y, type, style, direction, out TileObject objectData, false, false))
            {
                return(false);
            }

            objectData.random = random;
            if (TileObject.Place(objectData))
            {
                WorldGen.SquareTileFrame(x, y, true);

                if (!mute)
                {
                    Main.PlaySound(SoundID.Dig, x * 16, y * 16, 1, 1f, 0f);
                }

                return(true);
            }
            return(false);
        }
예제 #11
0
        public static int PlaceChest(int x, int y, ushort type = 21, bool notNearOtherChests = false, int style = 0)
        {
            int        num        = -1;
            TileObject tileObject = default(TileObject);

            if (TileObject.CanPlace(x, y, (int)type, style, 1, out tileObject, false, false))
            {
                bool flag = true;
                if (notNearOtherChests && Chest.NearOtherChests(x - 1, y - 1))
                {
                    flag = false;
                }
                if (flag)
                {
                    TileObject.Place(tileObject);
                    num = CreateChest(tileObject.xCoord, tileObject.yCoord, -1);
                }
            }
            else
            {
                num = -1;
            }
            if (num != -1 && Main.netMode == 1 && type == 21)
            {
                NetMessage.SendData(34, -1, -1, null, 0, (float)x, (float)y, (float)style, 0, 0, 0);
            }
            if (num != -1 && Main.netMode == 1 && type == 467)
            {
                NetMessage.SendData(34, -1, -1, null, 4, (float)x, (float)y, (float)style, 0, 0, 0);
            }
            if (num != 1 && Main.netMode == 1 && type >= 470 && TileID.Sets.BasicChest[type])
            {
                NetMessage.SendData(34, -1, -1, null, 100, (float)x, (float)y, (float)style, 0, type, 0);
            }
            return(num);
        }
예제 #12
0
        void Apply()
        {
            switch (mode)
            {
            case 0: {
                GenRunners.VeinRunner(
                    i: (int)p.Dequeue(),
                    j: (int)p.Dequeue(),
                    strength: (double)p.Dequeue(),
                    speed: (Vector2)p.Dequeue(),
                    length: (double)p.Dequeue(),
                    twist: (float)p.Dequeue(),
                    randomtwist: (bool)p.Dequeue());
                break;
            }

            case 1: {
                int     i        = (int)p.Dequeue();
                int     j        = (int)p.Dequeue();
                double  strength = (double)p.Dequeue();
                Vector2 speed    = (Vector2)p.Dequeue();
                Stack <((Vector2, Vector2), byte)> veins = new Stack <((Vector2, Vector2), byte)>();
                double length    = (double)p.Dequeue();
                float  twist     = (float)p.Dequeue();
                bool   twistRand = (bool)p.Dequeue();
                veins.Push(((new Vector2(i, j), speed), (p.Count > 0 ? (byte)p.Dequeue() : (byte)10)));
                ((Vector2 p, Vector2 v)v, byte count)curr;
                (Vector2 p, Vector2 v)ret;
                byte count;
                while (veins.Count > 0)
                {
                    curr  = veins.Pop();
                    count = curr.count;
                    ret   = GenRunners.VeinRunner(
                        i: (int)curr.v.p.X,
                        j: (int)curr.v.p.Y,
                        strength: strength,
                        speed: curr.v.v,
                        length: length,
                        twist: twist,
                        randomtwist: twistRand);
                    if (count > 0 && Main.rand.Next(3) == 0)
                    {
                        veins.Push(((ret.p, ret.v.RotatedBy(Main.rand.NextBool() ? -1 : 1)), (byte)Main.rand.Next(--count)));
                    }
                    if (count > 0)
                    {
                        veins.Push(((ret.p, ret.v.RotatedByRandom(0.05)), --count));
                    }
                }
                break;
            }

            case 2:
                World.BiomeData.RivenHive.Gen.StartHive((int)p.Dequeue(), (int)p.Dequeue());
                break;

            case 3:
                World.BiomeData.RivenHive.Gen.HiveCave((int)p.Dequeue(), (int)p.Dequeue());
                break;

            case 4:
                World.BiomeData.BrinePool.Gen.BrineStart((int)p.Dequeue(), (int)p.Dequeue());
                break;

            case 5:
                World.BiomeData.DefiledWastelands.Gen.StartDefiled((int)p.Dequeue(), (int)p.Dequeue());
                break;

            case 6: {
                Vector2 a = new Vector2((float)p.Dequeue(), (float)p.Dequeue());
                World.BiomeData.DefiledWastelands.Gen.DefiledRibs((int)a.X, (int)a.Y);
                for (int i = (int)a.X - 1; i < (int)a.X + 3; i++)
                {
                    for (int j = (int)a.Y - 2; j < (int)a.Y + 2; j++)
                    {
                        Main.tile[i, j].active(false);
                    }
                }
                TileObject.CanPlace((int)a.X, (int)a.Y, (ushort)ModContent.TileType <Tiles.Defiled.Defiled_Heart>(), 0, 1, out var data);
                TileObject.Place(data);
                break;
            }
            }
        }
예제 #13
0
        //in Terraria.WorldGen.TileFrame after if else chain inside frameImportant if statement before return add
        //  else { TileLoader.CheckModTile(i, j, num); }
        //in Terraria.TileObject.CanPlace add optional checkStay parameter as false to end
        //  and add && !checkStay to if statement that sets flag4
        public static void CheckModTile(int i, int j, int type)
        {
            if (WorldGen.destroyObject)
            {
                return;
            }
            TileObjectData tileData = TileObjectData.GetTileData(type, 0, 0);

            if (tileData == null)
            {
                return;
            }
            int frameX = Main.tile[i, j].frameX;
            int frameY = Main.tile[i, j].frameY;
            int subX   = frameX / tileData.CoordinateFullWidth;
            int subY   = frameY / tileData.CoordinateFullHeight;
            int wrap   = tileData.StyleWrapLimit;

            if (wrap == 0)
            {
                wrap = 1;
            }
            int subTile   = tileData.StyleHorizontal ? subY * wrap + subX : subX * wrap + subY;
            int style     = subTile / tileData.StyleMultiplier;
            int alternate = subTile % tileData.StyleMultiplier;

            for (int k = 0; k < tileData.AlternatesCount; k++)
            {
                if (alternate >= tileData.Alternates[k].Style && alternate <= tileData.Alternates[k].Style + tileData.RandomStyleRange)
                {
                    alternate = k;
                    break;
                }
            }
            tileData = TileObjectData.GetTileData(type, style, alternate + 1);
            int partFrameX      = frameX % tileData.CoordinateFullWidth;
            int partFrameY      = frameY % tileData.CoordinateFullHeight;
            int partX           = partFrameX / (tileData.CoordinateWidth + tileData.CoordinatePadding);
            int partY           = 0;
            int remainingFrameY = partFrameY;

            while (remainingFrameY > 0)
            {
                remainingFrameY -= tileData.CoordinateHeights[partY] + tileData.CoordinatePadding;
                partY++;
            }
            i -= partX;
            j -= partY;
            int        originX = i + tileData.Origin.X;
            int        originY = j + tileData.Origin.Y;
            TileObject objectData;
            bool       partiallyDestroyed = false;

            for (int x = i; x < i + tileData.Width; x++)
            {
                for (int y = j; y < j + tileData.Height; y++)
                {
                    if (!Main.tile[x, y].active() || Main.tile[x, y].type != type)
                    {
                        partiallyDestroyed = true;
                        break;
                    }
                }
                if (partiallyDestroyed)
                {
                    break;
                }
            }
            if (partiallyDestroyed || !TileObject.CanPlace(originX, originY, type, style, 0, out objectData, true, true))
            {
                WorldGen.destroyObject = true;
                for (int x = i; x < i + tileData.Width; x++)
                {
                    for (int y = j; y < j + tileData.Height; y++)
                    {
                        if (Main.tile[x, y].type == type && Main.tile[x, y].active())
                        {
                            WorldGen.KillTile(x, y, false, false, false);
                        }
                    }
                }
                KillMultiTile(i, j, frameX - partFrameX, frameY - partFrameY, type);
                WorldGen.destroyObject = false;
                for (int x = i - 1; x < i + tileData.Width + 2; x++)
                {
                    for (int y = j - 1; y < j + tileData.Height + 2; y++)
                    {
                        WorldGen.TileFrame(x, y, false, false);
                    }
                }
            }
        }
예제 #14
0
        public static bool TrySpawningTombstone()
        {
            int  PositionX = 0, PositionY = 0;
            bool Success = false;

            PositionX = Main.rand.Next((int)Main.leftWorld / 16 + 2, (int)Main.rightWorld / 16 - 4);
            PositionY = Main.rand.Next((int)(Main.worldSurface * 0.35f), (int)(Main.worldSurface * 0.95f));
            bool BlockedTilePosition = false;

            for (int x = -1; x < 2; x++)
            {
                Tile tile = Main.tile[PositionX + x, PositionY];
                if ((tile.active() && Main.tileSolid[tile.type]) || tile.wall > 0 || tile.liquid > 0)
                {
                    BlockedTilePosition = true;
                    break;
                }
            }
            if (!BlockedTilePosition)
            {
                bool GroundBellow = false;
                while (true)
                {
                    byte FloorCount = 0;
                    PositionY++;
                    if (PositionY >= Main.worldSurface)
                    {
                        break;
                    }
                    bool InvalidTile = false;
                    for (int x = -1; x < 2; x++)
                    {
                        Tile tile = Main.tile[PositionX + x, PositionY];
                        if (tile.active() && Main.tileSolid[tile.type] && tile.type != 192 && tile.liquid == 0)
                        {
                            switch (tile.type)
                            {
                            case TileID.CorruptGrass:
                            case TileID.Ebonstone:
                            case TileID.Ebonsand:
                            case TileID.FleshGrass:
                            case TileID.Crimtane:
                            case TileID.Crimsand:
                            case TileID.LeafBlock:
                            case TileID.LivingWood:
                            case TileID.BlueDungeonBrick:
                            case TileID.GreenDungeonBrick:
                            case TileID.PinkDungeonBrick:
                                InvalidTile = true;
                                break;
                            }
                            if (!InvalidTile)
                            {
                                FloorCount++;
                            }
                        }
                    }
                    if (InvalidTile)
                    {
                        break;
                    }

                    if (FloorCount == 1)
                    {
                        break;
                    }
                    else if (FloorCount == 2)
                    {
                        if (Main.tile[PositionX, PositionY - 1].wall == 0)
                        {
                            GroundBellow = true;
                        }
                        break;
                    }
                }
                if (GroundBellow)
                {
                    PositionY -= 1;
                    TileObject to;
                    TileObject.CanPlace(PositionX, PositionY, TileID.Tombstones, Main.rand.Next(255) == 0 ? 9 : 4, 1, out to);
                    if (TileObject.CanPlace(PositionX, PositionY, TileID.Tombstones, Main.rand.Next(255) == 0 ? 9 : 4, 1, out to))//(Main.tile[PositionX, PositionY].active() && Main.tile[PositionX, PositionY].type == TileID.Tombstones)
                    {
                        TileObject.Place(to);
                        System.Threading.Thread.Sleep(1000);
                        TombstoneTileX = PositionX;
                        TombstoneTileY = PositionY;
                        int signpos = Sign.ReadSign(PositionX, PositionY);
                        if (signpos > -1)
                        {
                            if (Main.sign[signpos] == null)
                            {
                                Main.sign[signpos] = new Sign();
                            }
                            Sign.TextSign(signpos, TombstoneText);
                        }
                        NPC.NewNPC(TombstoneTileX * 16, TombstoneTileY * 16, ModContent.NPCType <Npcs.AlexNPC>());
                        SpawnedTombstone = true;
                        Success          = true;
                    }
                }
            }
            return(Success);
        }
예제 #15
0
            public static void StartDefiled(float i, float j)
            {
                const float strength      = 2.8f;          //width of tunnels
                const float wallThickness = 3.1f;
                const float distance      = 40;            //tunnel length
                ushort      stoneID       = (ushort)ModContent.TileType <Defiled_Stone>();
                ushort      stoneWallID   = (ushort)ModContent.WallType <Defiled_Stone_Wall>();
                Vector2     startVec      = new Vector2(i, j);

                fisureCount = 0;
                DefiledCave(i, j);
                Queue <(int generation, (Vector2 position, Vector2 velocity))> veins = new Queue <(int generation, (Vector2 position, Vector2 velocity))>();
                int     startCount = genRand.Next(4, 9);
                float   maxSpread  = 3f / startCount;
                Vector2 vel;

                for (int count = startCount; count > 0; count--)
                {
                    vel = Vector2.UnitX.RotatedBy((MathHelper.TwoPi * (count / (float)startCount)) + genRand.NextFloat(-maxSpread, maxSpread));
                    veins.Enqueue((0, (startVec + vel * 16, vel)));
                }
                (int generation, (Vector2 position, Vector2 velocity)data)current;
                (int generation, (Vector2 position, Vector2 velocity)data)next;
                List <Vector2> fisureCheckSpots = new List <Vector2>();
                Vector2        airCheckVec;

                while (veins.Count > 0)
                {
                    current = veins.Dequeue();
                    int endChance = genRand.Next(1, 5) + genRand.Next(0, 4) + genRand.Next(0, 4);
                    int selector  = genRand.Next(4);
                    if (endChance <= current.generation)
                    {
                        if (genRand.Next(veins.Count) < 6 - fisureCheckSpots.Count)
                        {
                            selector = 3;
                        }
                    }
                    else if (selector == 3 && genRand.Next(veins.Count) > 6 - fisureCheckSpots.Count)
                    {
                        selector = genRand.Next(3);
                    }
                    switch (selector)
                    {
                    case 0:
                    case 1: {
                        next = (current.generation + 1,
                                DefiledVeinRunner(
                                    (int)current.data.position.X,
                                    (int)current.data.position.Y,
                                    strength * genRand.NextFloat(0.9f, 1.1f),                                                                              //tunnel width randomization
                                    current.data.velocity.RotatedBy(genRand.NextBool() ? genRand.NextFloat(-0.6f, -0.1f) : genRand.NextFloat(0.2f, 0.6f)), //random rotation
                                    genRand.NextFloat(distance * 0.8f, distance * 1.2f),                                                                   //tunnel length
                                    stoneID,
                                    wallThickness,
                                    wallType: stoneWallID));
                        airCheckVec = next.data.position;
                        if (airCheckVec.Y < Main.worldSurface && Main.tile[(int)airCheckVec.X, (int)airCheckVec.Y].wall == WallID.None)
                        {
                            break;
                        }
                        if (endChance > current.generation)
                        {
                            veins.Enqueue(next);
                        }
                        break;
                    }                            //single vein

                    case 2: {
                        next = (current.generation + 2,
                                DefiledVeinRunner(
                                    (int)current.data.position.X,
                                    (int)current.data.position.Y,
                                    strength * genRand.NextFloat(0.9f, 1.1f),
                                    current.data.velocity.RotatedBy(-0.4f + genRand.NextFloat(-1, 0.2f)),
                                    genRand.NextFloat(distance * 0.8f, distance * 1.2f),
                                    stoneID,
                                    wallThickness,
                                    wallType: stoneWallID));
                        airCheckVec = next.data.position;
                        if (airCheckVec.Y < Main.worldSurface && Main.tile[(int)airCheckVec.X, (int)airCheckVec.Y].wall == WallID.None)
                        {
                            break;
                        }
                        if (endChance > current.generation)
                        {
                            veins.Enqueue(next);
                        }
                        next = (current.generation + 2,
                                DefiledVeinRunner(
                                    (int)current.data.position.X,
                                    (int)current.data.position.Y,
                                    strength * genRand.NextFloat(0.9f, 1.1f),
                                    current.data.velocity.RotatedBy(0.4f + genRand.NextFloat(-0.2f, 1)),
                                    genRand.NextFloat(distance * 0.8f, distance * 1.2f),
                                    stoneID,
                                    wallThickness,
                                    wallType: stoneWallID));
                        airCheckVec = next.data.position;
                        if (airCheckVec.Y < Main.worldSurface && Main.tile[(int)airCheckVec.X, (int)airCheckVec.Y].wall == WallID.None)
                        {
                            break;
                        }
                        if (endChance > current.generation)
                        {
                            veins.Enqueue(next);
                        }
                        break;
                    }                            //split vein

                    case 3: {
                        next = (current.generation + 2,
                                DefiledVeinRunner(
                                    (int)current.data.position.X,
                                    (int)current.data.position.Y,
                                    strength * genRand.NextFloat(0.9f, 1.1f),
                                    current.data.velocity.RotatedBy(genRand.NextBool() ? genRand.NextFloat(-0.4f, -0.2f) : genRand.NextFloat(0.2f, 0.4f)),
                                    genRand.NextFloat(distance * 0.8f, distance * 1.2f),
                                    stoneID,
                                    wallThickness,
                                    wallType: stoneWallID));
                        airCheckVec = next.data.position;
                        if (airCheckVec.Y < Main.worldSurface && Main.tile[(int)airCheckVec.X, (int)airCheckVec.Y].wall == WallID.None)
                        {
                            break;
                        }
                        if (endChance > next.generation)
                        {
                            veins.Enqueue(next);
                        }
                        float size = genRand.NextFloat(0.3f, 0.4f);
                        if (airCheckVec.Y >= Main.worldSurface)
                        {
                            DefiledCave(next.data.position.X, next.data.position.Y, size);
                        }
                        DefiledRib(next.data.position.X, next.data.position.Y, size * 30, 0.75f);
                        fisureCheckSpots.Add(next.data.position);
                        break;
                    }                            //vein & cave
                    }
                }
                ushort fissureID = (ushort)ModContent.TileType <Defiled_Fissure>();

                while (fisureCount < 6 && fisureCheckSpots.Count > 0)
                {
                    int ch = genRand.Next(fisureCheckSpots.Count);
                    for (int o = 0; o > -5; o = o > 0 ? -o : -o + 1)
                    {
                        Vector2 p    = fisureCheckSpots[ch];
                        int     loop = 0;
                        for (; !Main.tile[(int)p.X, (int)p.Y + 1].active(); p.Y++)
                        {
                            if (++loop > 10)
                            {
                                break;
                            }
                        }
                        if (TileObject.CanPlace((int)p.X, (int)p.Y, fissureID, 0, 0, out TileObject to))
                        {
                            WorldGen.Place2x2((int)p.X, (int)p.Y, fissureID, 0);
                            fisureCount++;
                            break;
                        }
                    }
                    fisureCheckSpots.RemoveAt(ch);
                }
                Main.NewText(fisureCount);
            }